java中子类继承父类默认方法时优先于接口默认方法;若父类与接口同名默认方法冲突且子类未重写,则编译报错,必须显式覆盖以消除歧义。

Java中当子类继承了一个含有默认方法的父类,又实现了同名方法的接口时,优先级由“类优先于接口”原则决定:子类直接继承父类的默认方法,不会自动调用接口的默认方法;若父类和接口都定义了同签名默认方法,且子类未重写,则编译报错——必须显式覆盖以消除歧义。
继承父类默认方法时,接口同名默认方法被忽略
如果父类(比如 A)定义了 void test() 默认方法,子类 B extends A 又 implements I(I 也有 default void test()),只要父类方法可访问(非 private、包内可见或 public),子类实例调用 test() 就执行父类版本,接口的默认方法不会参与调度。
父类与接口默认方法冲突时必须显式重写
当父类和所实现接口都提供了同签名的默认方法,且子类未提供具体实现,编译器会拒绝编译。例如:
- class Parent { public void method() { System.out.println("Parent"); } }
- interface I { default void method() { System.out.println("Interface"); } }
- class Child extends Parent implements I → 编译失败,提示 “class Child inherits unrelated defaults for method() from types Parent and I”
解决方式是子类中显式写出 public void method(),内部可选择调用 super.method() 或 I.super.method(),或自定义逻辑。
多个接口默认方法冲突的处理逻辑一致
即使没有父类,仅实现多个含同名默认方法的接口(如 I1 和 I2),子类也必须重写该方法。此时不存在“谁优先”,而是强制要求明确语义。一旦子类继承了父类默认方法,它就比所有接口默认方法层级更高,接口间的冲突不再触发——因为父类版本已“胜出”,除非它本身不可见(如 package-private 且跨包)。
注意 default 方法的可见性影响是否构成冲突
default 方法本质是 public 的,但能否被继承还取决于父类中该方法的修饰符:
- 父类方法为 private:子类无法继承,此时只看接口默认方法,多接口冲突需重写
- 父类方法为 protected 或 public:可被子类继承,压制接口默认方法
- 父类方法为包私有(无修饰符)且子类不在同一包:不可见,等效于无父类实现,回归接口冲突规则
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











