Java要求类实现多个含同名default方法的接口时必须显式重写该方法,否则编译报错;须用InterfaceName.super.methodName()调用指定接口默认实现,且仅限public default方法。

Java 中一个类实现多个接口时,若接口中存在同名同签名的 default 方法,编译器会直接报错,提示类似 “class inherits unrelated defaults for method() from types A and B”。这不是异常,而是 Java 的强制设计——它要求你明确表态,不能默认选择或静默继承。
必须显式重写该方法
只要冲突存在,你就得在实现类中用 @Override 提供完整的方法定义。哪怕两个默认方法逻辑完全一致,也不能省略;哪怕只是调用其中一个接口的实现,也必须写出来:
- 只声明方法签名、不写方法体 → 编译失败
- 方法体为空(
{})或仅抛异常 → 合法,但需确认是否符合业务语义 - 必须使用
InterfaceName.super.methodName()显式调用指定接口的默认实现
正确调用指定接口的默认实现
这是唯一合法访问某接口 default 方法的方式,语法严格,不可简写:
- 只能用于
public default方法,static或private default不参与冲突,也不支持该语法 - 不能写成
super.methodName()或this.super.xxx(),必须带具体接口名 - 可在方法体内组合调用,例如先执行
A.super.log(),再加日志增强或状态校验
优先级规则帮你避开冲突
不是所有同名方法都会触发冲突,Java 有清晰的优先级链:
立即学习“Java免费学习笔记(深入)”;
- 如果类继承了父类,且父类已有同名方法(无论抽象还是具体),则父类方法绝对优先,接口 default 方法被忽略
- 如果某个接口只声明了抽象方法(无 default),而其他接口提供了 default 实现,则抽象方法强制你实现,default 版本自动失效
- 只有当所有来源都是互不继承的接口、且都提供
public default方法时,才真正触发编译拦截
从源头减少冲突可能
与其总在实现类里“灭火”,不如在接口设计阶段预防:
- 接口方法命名尽量带领域前缀,比如
httpSend()、dbSave(),避免泛泛的send()、save() - 通用能力(如日志、重试、序列化)优先抽为工具类或抽象基类,而非塞进多个业务接口
- 谨慎添加 default 方法——它适合向后兼容的轻量增强,不适合承载核心可变行为


















