学完抽象类来学接口。
接口是什么?
接口不是类,而是对类的一组需求描述。比如我们的鼠标,U盘全都有统一的USB接口。任何实现了某一接口的类,都必须实现该接口规定的方法,如果只实现了一部分,那么这个子类必须声明为抽象类,这点和抽象类一样。
示例代码。
public interface Comparable
{
int compareTo(Object other);
}
//实现
class Employee implements Comparable
{
public int compareTo(Object otherObject)
{
Employee other = (Employee) otherObject;
return Double.compare(salary, other.salary);
}
}
有了抽象类,为什么还要接口
java中没有多继承的概念,为了实现多继承,引入了接口,可以同时实现多个接口。接口可以提供多继承的大多数好处,还能比秒多继承的复杂性和低效性。
接口中一些隐藏特性
- 接口中所有方法属于public,声明方法时,可以不提供关键字public。但是在实现接口的方法时,必须将接口声明为public,否则编译器认为是包可见。
- 接口不是类,不能实例化一个接口,但是可以用来声明,并且引用实现了接口的类对象。
- 可以使用instanceof来检查一个对象是否实现了某个特定的接口。
- 接口可以扩展,就是接口继承接口,和类的继承关系一样。
- 接口中不能包含实例域,但是可以包含常量,常量默认为public static fianl类型。
- 接口可以只有常量,只有方法,甚至是空的,比如Cloneable(见我的另一篇clone()方法的文章),这类接口就是用来标记类是否能够被克隆。
Java8中的新特性
之前认为接口中不能实现任何方法,现在增加了两种方法的实现。静态方法,和默认方法。静态方法就是static修饰的方法。默认方法是default修饰的方法。因为接口中的方法,我们可能只关注某几个实现。其它的可以不去实现它,直接使用接口中定义的默认方法。其次,默认方法方便兼容。如果接口中直接增加新特性。子类就会因为没有实现新方法而出错。但是如果增加的方法有默认实现,那么就能实现旧版代码的兼容。
如果现在一个接口中将一个方法定义为一个默认方法,然后又在超类或者另外的接口中定义了同样的方法,怎么做呢?
- 超类优先。如果超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略。超类优先可以确保Java7的兼容性。不要为Object中的方法定义默认方法,比如equals,toString,因为永远不会执行默认方法。
- 接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,必须覆盖这个方法来解决冲突。
接口与回调
回调callback是一种常见的程序设计模式。在这种设计模式下,可以指出某个特定事件发生时应该采取的动作。比如用定时器定时地调用某个方法。因为java面向对象,所以传入的是对象。要求这个对象的类实现java.awt.event包的ActionListener接口。这样就可以使用java.swing包中的Timer类在给定时间执行这个方法。
Comparator接口
不细讲了,用lambda表达式更容易实现。