在 Java 中,当子类同时继承抽象类并实现含默认方法的接口且二者定义了同名方法时,可通过 super.m1() 调用父类实现,而必须显式使用 InterfaceName.super.m1() 调用接口默认方法——这是由单继承与多实现语义差异决定的。
在 java 中,当子类同时继承抽象类并实现含默认方法的接口且二者定义了同名方法时,可通过 `super.m1()` 调用父类实现,而必须显式使用 `interfacename.super.m1()` 调用接口默认方法——这是由单继承与多实现语义差异决定的。
在 Java 的继承体系中,单继承(extends) 与 多实现(implements) 的设计哲学直接决定了方法调用语法的差异:由于一个类只能有一个直接父类,super.m1() 天然指向该父类的实现,无需额外限定;但一个类可实现多个含默认方法的接口,因此调用某接口的默认方法时,必须通过 InterfaceName.super.m1() 明确指定目标接口,避免歧义。
以下是一个规范、可运行的示例:
interface C { default void m1() { System.out.println("C (interface default)"); }}abstract class A { abstract void display(); void m1() { System.out.println("A (abstract class method)"); }}class B extends A implements C { @Override void display() { // ✅ 正确:调用父类 A 的 m1() super.m1(); // 输出: A (abstract class method) // ✅ 正确:显式调用接口 C 的默认方法 C.super.m1(); // 输出: C (interface default) // ❌ 错误写法(编译失败): // A.super.m1(); // 编译错误:"not an enclosing class" // 因为 A 是父类而非外围类(enclosing class),不能用 A.super } @Override void m1() { // 若需重写 m1 并组合两者逻辑,推荐在此处统一调用 super.m1(); // 父类实现 C.super.m1(); // 接口默认实现 }}
⚠️ 关键注意事项:
总结:Java 通过语法强制区分了单继承的确定性(super)与多接口的二义性(Interface.super),理解这一机制是编写清晰、可维护多层抽象结构的基础。
立即学习“Java免费学习笔记(深入)”;