在Java 8中出现了**默认方法(default methods)**的概念——这是在接口内部声明的带实现的方法。它们允许在不破坏与现有实现兼容性的情况下,向接口添加新方法。
语法:
public interface MyInterface { default void printHello() { System.out.println("Hello!"); } }
特点与细节:
Object类的方法(例如,equals,hashCode)。如果一个类实现了两个具有相同default方法的接口而没有重写该方法,会发生什么?
答案: 编译器会报错"class... inherits unrelated defaults for ... from types ... and ...",并要求在类中显式实现该方法。
示例:
interface A { default void doSomething() { System.out.println("A"); } } interface B { default void doSomething() { System.out.println("B"); } } class C implements A, B {} // 编译错误!
解决方案:
class C implements A, B { @Override public void doSomething() { A.super.doSomething(); // 或 B.super.doSomething() } }
故事
在一个团队项目中,为了迁移API在公共接口中添加了默认方法。旧的接口实现没有重写新方法,导致了意外的行为,因为执行的是默认实现而不是预期的逻辑。结果用户发现功能下降。
故事
在扩展库时,开发者在公共接口中添加了一个带有业务逻辑的默认方法。随后在另一个接口中添加具有不同行为的相同方法,导致了继承冲突,使新的实现无法编译。
故事
开发者试图在接口中使用一个名为
hashCode的默认方法,期望这会影响子类中该方法的重写,但编译器不允许这样做。这导致了对错误原因的长时间调查以及接口结构的重新设计。