抽象类方法优先级最高,完全屏蔽接口默认方法;仅当纯接口间存在同名public default方法且类继承链无同签名方法时才触发冲突;抽象方法强制子类实现,default版本不参与决策。

当一个类同时继承抽象类并实现多个接口,且三者存在同名方法时,Java 有明确的优先级规则:抽象类中的方法(无论是否 abstract)拥有最高优先权,接口默认方法自动失效,不参与冲突判定。
抽象类方法完全屏蔽接口默认方法
只要抽象类(或其任意父类)中声明了与接口默认方法同签名的方法,无论该方法是具体实现、abstract 声明,还是 protected/package-private 访问级别,编译器都会忽略所有接口的 default 版本。此时不会报“inherits unrelated defaults”错误,也不需要重写。
- 抽象类有 public void save() → 子类调用 save() 执行该实现,接口 default save() 不可见
- 抽象类有 abstract void save() → 子类必须提供 save() 实现,该实现即最终版本,接口 default save() 被跳过
- 即使接口 default 方法逻辑更贴合当前业务,也无法“覆盖”或“优先启用”,抽象类路径具有绝对控制力
只有纯接口间才触发默认方法冲突
真正的默认方法冲突仅发生在类实现两个及以上互不继承的接口,且这些接口都提供了同名、同参数列表的 public default 方法,同时类自身及其整个继承链中没有同签名的类方法(包括抽象类中的 abstract 或 concrete 方法)。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 示例:A 和 B 是独立接口,都定义 default void log(),类 C implements A, B → 必须在 C 中重写 log()
- 若 C extends BaseLogger,而 BaseLogger 已有 public void log() → 冲突消失,C 直接继承 BaseLogger 的版本
- 若 C implements A, B,且 A extends C(即 A 继承自 B),则不构成“无关默认”,通常不报错(除非菱形结构中 B 和 C 都覆写了祖先的 default)
抽象方法存在时,默认方法不参与决策
如果某个接口只声明 abstract void run(),另一个接口提供 default void run(),类同时实现二者,则抽象方法强制要求子类实现,default 版本彻底退出流程——这不是冲突,而是契约压倒实现。
立即学习“Java免费学习笔记(深入)”;
- 子类必须提供 run() 具体逻辑,不能依赖 interfaceB.super.run()
- 即便你写了 interfaceB.super.run(),也只是代码中的一次普通调用,不改变抽象方法必须实现这一根本约束
- 此时不存在编译错误,因为抽象方法的存在已提前锁定了行为归属

















