简体   繁体   English

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

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

Suppose I have the following code: 假设我有以下代码:

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?
    }
}

Now suppose "appropriate code for android reproduction" is best described by using "appropriate code for humanoid form reproduction" as a sub-routine. 现在假设通过使用“用于人形形式再现的适当代码”作为子例程来最好地描述“用于android再现的适当代码”。 How can I access "appropriate code for humanoid form" from within "appropriate code for android reproduction"? 如何从“适用于Android再现的代码”中访问“适合人形的代码”? I can think of three ways, but none of them works: 我可以想到三种方式,但它们都不起作用:

  • Simply invoking reproduce() invokes the overriding implementation. 只需调用reproduce()即可调用重写实现。
  • Writing ((HumanoidForm) this).reproduce() still invokes the overriding implementation. 写((HumanoidForm)this).reproduce()仍然调用重写的实现。
  • Mimicking the re-use of implementations of methods in super classes by overriding methods, one may think of writing super.reproduce(). 通过重写方法来模仿超类中方法实现的重用,可以考虑编写super.reproduce()。 However, that refers to Machine's implementation of reproduce, which may not even exist. 然而,这指的是机器的再现实现,甚至可能不存在。

So it seems there is no way to re-use the code in the default method for overriding. 所以似乎没有办法在默认方法中重用代码来覆盖。 Is that really so? 真的是这样吗?

HumanoidForm.super.reproduce();

Actually, you can choose freely the existing implementation. 实际上,您可以自由选择现有的实现。 Let me give you a scenario slightly more complicated than yours. 让我给你一个比你更复杂的场景。 To make things worse, all A , B & C has the same method signature. 更糟糕的是,所有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");
    }       
}

Now, I create a subclass to C which implements A & B: 现在,我创建了一个实现A&B的C子类:

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
    }
}

The output will be: 输出将是:

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

when you run : 当你

new Tester().doWork();

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

In particular the section where it says "If we want to specifically invoke one of the sayHi() methods in either InterfaceA or InterfaceB, we can also do as follows:" 特别是它所说的“如果我们想在InterfaceA或InterfaceB中专门调用sayHi()方法之一,我们也可以这样做:”

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? 真的是这样吗?

No, you can reuse the code. 不,您可以重用代码。 You can easily test it and you will see that the following code works: 您可以轻松地测试它,您将看到以下代码的工作原理:

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");
    }
}

OUTPUT: OUTPUT:

From default interface
From implementing class

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM