java 中子类选择实现时,优先使用最具体类的默认方法。如果冲突发生在同一继承层级的不同接口,子类必须显式重写该方法并指定调用来源。

当类直接继承父类且实现多个接口时如何解析
这种情况下遵循“类优先”原则,即父类的方法(无论是普通方法还是默认方法)优先级高于任何接口的默认方法。只要父类提供了同名同参的实现,编译器就不会报错,子类自然继承父类的逻辑,无需额外处理。

public class Animal {
public void speak() {
System.out.println("Animal speaks");
}
}
public interface Flyable {
default void speak() {
System.out.println("Flyable speaks");
}
}
public class Bird extends Animal implements Flyable {
// 不需要重写 speak,直接使用 Animal 的实现
}
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.speak(); // 输出: Animal speaks
}
}
运行上述代码,控制台将打印 Animal speaks。这验证了当 Animal 类存在 speak 方法时,即使 Bird 实现了包含默认方法的 Flyable 接口,依然以类定义为准。
立即学习“Java免费学习笔记(深入)”;
当多个接口提供相同默认方法时如何解决
如果类没有提供该方法的实现,且实现的多个接口都包含同名同参的默认方法,则会产生编译错误。此时必须在子类中显式重写该方法,并通过 Interface.super.method() 语法明确指定调用哪一个接口的默认实现。

public interface Swimmable {
default void speak() {
System.out.println("Swimmable speaks");
}
}
public interface Flyable {
default void speak() {
System.out.println("Flyable speaks");
}
}
public class Duck implements Swimmable, Flyable {
@Override
public void speak() {
Swimmable.super.speak(); // 显式选择 Swimmable 的实现
}
}
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.speak(); // 输出: Swimmable speaks
}
}
在 Duck 类中,如果不重写 speak 方法,编译器会提示 incompatible types。通过重写并调用 Swimmable.super.speak(),我们强制指定了行为来源,程序成功输出 Swimmable speaks。
当子类重写了冲突方法后实际执行的是哪个逻辑
一旦子类显式重写了冲突的默认方法,无论内部调用的是哪个接口的默认实现,后续所有对该方法的调用都将执行子类重写后的逻辑。这是多态的基本表现,重写后的方法完全覆盖了接口和父类的默认或普通实现。


















