在java单继承多实现机制下,子类可通过super.m1()调用唯一父类的方法,而必须通过interfacename.super.m1()显式指定接口以调用其默认方法,二者语法语义严格区分。
在java单继承多实现机制下,子类可通过super.m1()调用唯一父类的方法,而必须通过interfacename.super.m1()显式指定接口以调用其默认方法,二者语法语义严格区分。
在Java中,当一个类既继承抽象类又实现接口,且两者均定义了同名方法(如m1())时,子类重写该方法后,若需分别调用父类和接口中的实现,必须遵循明确的语法规范——这源于Java继承模型的根本差异:类是单继承的,接口是多实现的。
✅ 调用父类方法:由于Java只允许一个直接父类,super.m1()天然无歧义,会调用最近的父类(即extends声明的类)中定义的具体方法。你也可以显式写作B.super.m1()(其中B为当前子类名),但绝不能写成A.super.m1()——A是父类而非“外围类”,X.super语法仅适用于内部类访问外部类成员,不适用于继承链调用,因此编译器报错not an enclosing class: A。
✅ 调用接口默认方法:因一个类可实现多个接口(如同时implements C, D, E),super.m1()无法确定目标接口,故必须使用InterfaceName.super.m1() 显式限定,这是Java 8+引入的强制语法。
以下为正确实现示例:
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)
// ⚠️ 注意:B.super.m1()等价于super.m1(),合法但冗余
// B.super.m1(); // 同上,不推荐重复书写
}
@Override
void m1() {
// 若重写m1(),此处也可按需组合调用
super.m1(); // 父类A
C.super.m1(); // 接口C
}
}
⚠️ 关键注意事项:
- super.m1() 永远指向直接父类(A),与当前类名无关;ClassName.super.m1() 中的 ClassName 必须是当前类自身名称(如 B.super.m1()),不可替换为父类名。
- 接口调用必须带接口名前缀,且仅适用于default方法;若接口中是抽象方法(无实现),则无法通过Interface.super调用。
- 若父类方法为private或被子类覆盖为private,则不可通过super访问——super仅可访问protected、包内可见或public的非私有成员。
- 多层继承中,super始终指直接父类;如需调用祖父类方法,需在父类中提供代理方法,Java不支持super.super.m1()。
总结:理解super与Interface.super的本质区别,是掌握Java多重契约(inheritance + implementation)下方法分发的关键——前者依赖单继承的确定性,后者依靠显式命名解决多实现的歧义性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











