接口:
在java中不直接支持多继承,因为会出现调用的不确定性,所以java将多继承机制进行改良,在java中变成了多实现。一个类可以实现多个接口,一个接口可以继承多个接口。
什么是接口:
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用时,再根据具体情况把这些方法实现。接口由全局变量和抽象方法组成。接口是更加抽象的抽象的抽象类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体【jdk7.0】,即接口中的方法必须全部是抽象方法,接口体现了程序设计的多态和高内聚和低耦合的设计思想。(注:jdk8.0后接口类可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现。)
接口的语法规则:
访问修饰符 interface 接口名{ };
我们使用interface关键字声明一个接口,只声明方法标示,不声明方法体
public interface flying{
publlic int speed = 10;
public void takeoff();
public void land();
}
接口不能直接使用,必须有对应的实现类,使用implemments关键字去实现接口,如果实现类不是抽象类就必须实现接口的所有抽象方法
public class plane implements flying{
private String name;//名称,类属属性和接口无关
@Override
public void takeoff(){
System.out.println("只要速度快就能飞");
}
@Override
public void land(){
System.out.println("降落……");
}
}
通过接口定义变量,使用具体类的事例,进行调用
public static void main (String[] args){
flying obj = new plane();
obj.takeoff();
obj.land();
}
一般建议接口名称使用形容词,外部接口范围限定词可以使用public或者默认package,内部接口4个都能使用,如果定义public接口,则规定和定义public类一致,要求接口名称和文件名称一致
接口注意事项:
- 接口是一种特殊的抽象类,接口只能被abstract或者public修饰。实际上从语法的角度上说,外部接口还允许package范围限定,但是跨包不能访问,所以不使用
- 没有构造器方法
- 没有属性,只能定义常量
- 可以包含抽象方法,也可以没有抽象方法。Jdk1.8以前开始允许在方法前添加关键字default定义方法的默认实现
- 在jdk1.8中允许在接口中定义静态方法,可以使用default关键字给抽象方法提供默认实现。有默认实现的方法在现实类中可以重新定义,也可以重新不定义
- 抽象方法必须在实现类中提供实现
- 允许一个类实现多个接口,但是每个接口的抽象方法都必须提供实现,否则是抽象类。提供的实现也可以是继承。首先通过接口定义调用的规范然后使用抽象类实现接口,其中定义公共类实现最后定义子类继承抽象类,实现所有的抽象方法
接口的实现避免了单继承的局限性,这样定义C接口则拥有A+B的所有定义,可以使用A和B接口以及父类D声明变量类型,直接new T。但结束时,用谁声明变量编译器系统识别就是谁这种类型,也就意味只能调用识别类型中的方法,不能调用其他方法
接口的特殊特征:
一个类只能有一个父类
一个类可以实现多个接口
一个接口可以继承多个接口
接口的作用:
统一访问
解耦 通过接口可以隔离具体实现,解耦就是在使用和实现者之间没有关系,无论实现者如何改 变实现,对于使用者使用不会变化
接口和抽象类的异同点:
相同点:都是不断向上抽取而来
不同点:
1.抽象类需要被继承,而且只能单继承,接口需要被实现,而且可以多实现
2.抽象类中可以定义抽象方法和非抽象方法子类继承后可以直接使用抽象方法定义抽象类的主要目 的是在于延迟实现方法和公共方法骨架
3.接口中只能定义抽象方法,必须由子类去实现;jdk1.8+中允许接口的方法有默认实现,实现类 中可以直接使用默认实现,允许覆盖定义
4.抽象类的继承是is a关系。在定义该体系的基本共性内容
5.接口的实现是like a关系,在定义体系额外功能
6.接口中只能定义常量,而且必须被初始化,抽象类中可以定义属性,允许在声明时直接初始化, 也可以不初始化,同时允许定义常量
7.接口中的方法必须全部是抽象的(JDK1.8+版本)中可以通过default关键字定义方法的默认实 现,允许定义静态方法),抽象类中可以有抽象方法也可以由普通方法
如何使用接口
一般使用接口隔离具体实现,可以将类之间的相互依赖变为类对接口的依赖。例如出差类和会飞的东西,是通过会飞的接口进行隔离,这样不管出差类需要修改或者会飞的东西需要修改,都不会相互影响,如果一组相关的类中有公共的方法和特殊的方法,可以使用抽象类,在抽象类中固化公共的方法,而无,需具体子类重复实现;但是在抽象类中无法实现的方法可以延退到子类中再实现。例如排序器Bubblesorter,其中抽象类 Bubblesorteri固化了所使用的冒泡排序算法,而将无法实现的 bigger比较算法延迟到 Bubble Sorter的子类 Pigsorterc中实现,同时 Pigsortert中也不需要重新定义排序算法
最佳软件开发实践:先定义接口规范调用方法,在使用抽象类实现接口定义公共方法,最后再定义具体子类实现所有的方法
接口和抽象类的使用场景
从设计层面看,抽象类体现继承关系is a,它主要描述类的从属关系或者父子关系,抽象类和它的派生类之间是典型的IS-A关系,即子is a父。interfacer可以多实现,而且不要求实现者和 nterface定义在概念本质上是一致的,仅仅是实现了,interface定义的契约而已。它主要描述的是类型间的行为合同,接口和它的实现类之间是典型的CAN-DO关系,即子 can do父
为什么接口需要默认方法?
在接口添加默认方法不需要修改实现类,接口新增的默认方法在实现类中直接可用。
Comparable和Comparator接口
Comparable接口
含义是可比较的,如果对象所在的类实现了 Comparable接口,这类对象就是可以进行大小的比较,接口就是用于指定对象排序规则的。
此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareto方法被称为它的自然比较方法。实现此接口的对象列表(和数组)可以通过 Collections. sort(和Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。
强烈推荐(虽然不是必需的)使自然排序与 equals一致。所谓与 equals-致是指对于类C的每一个e1和e2来说,当且仅当(e1. compareto( Object)e2)==0)与e1. equals( Object)e2)具有相同的布尔值时,类C的自然排序才叫做与 equals一致