
在Java中,当一个类同时继承抽象类并实现接口(且二者定义了同名方法)时,可通过super.m1()调用父类实现,通过InterfaceName.super.m1()调用接口默认方法;直接写A.super.m1()会编译错误,因super不支持显式指定父类名。
在java中,当一个类同时继承抽象类并实现接口(且二者定义了同名方法)时,可通过`super.m1()`调用父类实现,通过`interfacename.super.m1()`调用接口默认方法;直接写`a.super.m1()`会编译错误,因`super`不支持显式指定父类名。
Java 的继承机制决定了子类对父类方法和接口默认方法的调用方式存在本质区别:单继承 vs 多实现。
由于 Java 只允许单继承(一个类只能有一个直接父类),编译器能唯一确定 super 所指的父类。因此,调用父类中定义的具体方法(包括非 abstract 的普通方法)时,只需使用 super.m1() 即可——无需、也不能显式写出父类名(如 A.super.m1() 是非法语法,会报错 “not an enclosing class”)。
而接口支持多实现,当多个接口提供同名默认方法时,必须明确指定目标接口以避免歧义。因此,调用接口的默认方法必须使用 InterfaceName.super.m1() 的形式,这是 Java 8 引入的强制语法。
下面是一个完整、可运行的示例:
立即学习“Java免费学习笔记(深入)”;
interface C {
default void m1() {
System.out.println("C (interface default method)");
}
}
abstract class A {
abstract void display();
void m1() {
System.out.println("A (abstract class concrete method)");
}
}
class B extends A implements C {
@Override
void display() {
// ✅ 正确:调用父类 A 的 m1()
super.m1(); // 输出: A (abstract class concrete method)
// ✅ 正确:调用接口 C 的默认方法
C.super.m1(); // 输出: C (interface default method)
}
@Override
void m1() {
// 若需重写并组合两者逻辑,也可在此处调用
super.m1(); // 父类实现
C.super.m1(); // 接口默认实现
}
}
public class Main {
public static void main(String[] args) {
B obj = new B();
obj.display(); // 触发上述两行调用
// 输出:
// A (abstract class concrete method)
// C (interface default method)
}
}⚠️ 注意事项:
- super.m1() 永远指向直接父类(即 A)中定义的方法,不可用于调用接口方法;
- C.super.m1() 仅适用于当前类直接实现的接口,且该接口必须声明了 default 方法;
- 若父类 A 中的 m1() 是 abstract 的,则 super.m1() 不合法(不能调用抽象方法),此时必须由子类提供实现;
- 不要尝试 A.super.m1() 或 B.super.m1()——super 关键字本身不接受类型前缀,这是语法错误。
总结:理解 super 的语义边界是关键——它代表“直接父类的实例上下文”,而接口默认方法属于“静态绑定到特定接口”的行为,需显式限定。合理运用这两种调用方式,可清晰分离继承链与契约契约(interface contract)的职责,提升代码可维护性与设计透明度。


















