梳理 `default` 方法如何解决接口演进与默认逻辑下放
JDK 1.8 前,接口只能声明抽象方法,若要提供共享逻辑必须借助单继承的抽象类。JDK 8 引入 default 关键字,允许在接口中编写带方法体的默认实现,甚至还能定义 static 静态方法。这解决了接口向后演进的痛点,例如 List.sort() 就是默认方法,无需修改所有实现类即可丰富接口功能。
诊断题
default 方法?两者在设计上的核心妥协点是什么?答案骨架
我能梳理 default 方法的机制
- 它解决了老接口新增方法会导致所有实现类编译报错的演进痛点
- 核心机制是在接口中用
default关键字声明带方法体的方法 - 边界是它不能完全替代抽象类,因为接口仍不能持有状态(实例变量)
- 关联到
static方法,两者都不计入函数式接口的抽象方法数量。
边界追问
default 方法的接口,此时编译器会报错还是优先选择父类方法?边界答案
default 方法,编译器会直接调用父类实现,不会产生歧义报错;但如果两个接口提供了相同的 default 方法且没有父类覆盖,则必须由实现类重写解决冲突。记忆锚点
default 送来默认体,单继承不再是坎。衍生拓展
- 探讨接口多继承时
default方法的“菱形继承”冲突解决方案。 - 结合
Collection源码分析stream()和parallelStream()的默认实现原理。 - 对比
default方法与抽象类普通方法在多态调用时的字节码差异。
落地场景
演示如何给自定义接口增加带实现的默认方法,让匿名内部类直接复用。
1interface IFormula {
2 double calculate(int a);
3 default double sqrt(int a) {
4 return Math.sqrt(a);
5 }
6}
7IFormula f = new IFormula() {
8 public double calculate(int a) { return a * a; }
9};
10System.out.println(f.sqrt(100));