接口
接口是对类需求的描述(是一种行为约束或功能)。实现接口的非抽象类要对接口描述的行为给出具体实现过程
接口是没有实例域的抽象类
- 接口中的所有方法都自动设为
public - 接口中的域都自动设为
public static final
JDK1.8 接口方法允许具体实现
- 静态方法
public interface Path {
public static Path get(String first,String ... more){
// do something
}
}
- 默认方法
public interface Path extends Comparable<Path> {
@Override
default int compareTo(Path o) {
return 0;
}
}
接口中用 default 修饰符标记 的方法
默认方法只实现自己关心的方法,其他方法可以什么都不做
默认方法可以调用其他方法
public interface Path {
int size();
default boolean isEmpty(Path o) {
return size() == 0;
}
}
接口演化
为接口增加非默认方法不能保证 “源代码兼容” 。使用默认方法可以保证接口新增默认方法后,其实现类仍正常加载,不会有意外发生。(为接口增加方法可以保证“二进制兼容”)
接口与抽象类
- 抽象类的缺点 :单继承
- 接口允许多继承
接口方法冲突
当前类有继承关系和实现多接口的情况,超类和接口中或存在相同的方法定义,这里存在一个二义性
- 超类优先 只会考虑超类方法,接口的所有默认方法都会被忽略
- 接口冲突
class Student implements Person, Named{
public String getName(){
return Person.super.getName(); // 在实现方法中选择要实现的接口,进行覆盖
}
}
接口中不要重写定义Object类中的方法,由于“类优先”原则,这样的方法绝对无法超越 Object.toString 或 Object.equals
接口回调 callback
某个特定事件发生时应该采取的动作
接口的类型
- 标记接口
tagging interface接口中不包含任何方法,唯一的作用就是运行在类型查询中使用instanceof
if ( obj instanceof Cloneable) ...
建议不要使用标记接口
- 函数式接口
functional interface只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。