如何在覆盖实现中调用接口的方法的默认实现?

How to invoke an interface's default implementation of a method in an overriding implementation?

假设我有以下代码:

interface HumanoidForm {
    default HumanoidForm reproduce() {
        <appropriate code for humanoid form reproduction>
    }
}

class Android extends Machine implements HumanoidForm {
    public HumanoidForm reproduce() {
        <appropriate code for android reproduction> // how to use HumanoidForm's default implementation here?
    }
}

现在假设 "appropriate code for android reproduction" 最好用 "appropriate code for humanoid form reproduction" 作为子例程来描述。如何从 "appropriate code for android reproduction" 中访问 "appropriate code for humanoid form"?我可以想到三种方法,但其中 none 行得通:

所以似乎没有办法重新使用默认方法中的代码进行覆盖。真的是这样吗?

HumanoidForm.super.reproduce();

看看这个:https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/

特别是说 "If we want to specifically invoke one of the sayHi() methods in either InterfaceA or InterfaceB, we can also do as follows:"

的部分
public class MyClass implements InterfaceA, InterfaceB {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
}

@Override
public void saySomething() {
    System.out.println("Hello World");
}

@Override
public void sayHi() {
   InterfaceA.super.sayHi();
}

}

interface InterfaceA {

public void saySomething();

default public void sayHi() {
    System.out.println("Hi from InterfaceA");
}

}

interface InterfaceB {
 default public void sayHi() {
    System.out.println("Hi from InterfaceB");
}
}

So it seems there is no way to re-use the code in the default method for overriding. Is that really so?

不,您可以重复使用代码。您可以轻松地对其进行测试,您将看到以下代码有效:

public class Test implements HumanoidForm
{             
    public static void main(String[] args) 
    {       
        new Test().reproduce();         
    }   

    @Override
    public void reproduce(){
        HumanoidForm.super.reproduce();  //Invoking default method
        System.out.println("From implementing class");
    }       
}

interface HumanoidForm {
    default void reproduce() {
       System.out.println("From default interface");
    }
}

输出:

From default interface
From implementing class

实际上,您可以自由选择现有的实现。让我给你一个比你的稍微复杂的场景。更糟糕的是,所有 ABC 都具有相同的方法签名。

interface A {
    default void doWork() {
       System.out.println("Default implementation From A");
    }
}

interface B{
    default void doWork() {
      System.out.println("Default implementation From B");  
    }   
}

class C{
    void doWork(){
        System.out.println("Default implementation From C");
    }       
}

现在,我创建一个 C 的子类来实现 A 和 B:

class Tester extends C implements A, B
{
    @Override public void doWork(){
        A.super.doWork();  //Invoke A's implementation
        B.super.doWork();  //Invoke B's implementation
        super.doWork();    //Invoke C's implementation
    }
}

输出将是:

Default implementation From A
Default implementation From B
Default implementation From C

当你运行:

new Tester().doWork();