如何在覆盖实现中调用接口的默认方法实现?
假设我有以下代码:
interface HumanoidForm { default HumanoidForm reproduce() { } } class Android extends Machine implements HumanoidForm { public HumanoidForm reproduce() { // how to use HumanoidForm's default implementation here? } }
现在假设通过使用“用于人形forms再现的适当代码”作为子例程来最好地描述“用于android再现的适当代码”。 如何从“适用于Android复制的代码”中访问“适合人形的代码”? 我可以想到三种方式,但它们都不起作用:
- 只需调用reproduce()即可调用重写实现。
- 写((HumanoidForm)this).reproduce()仍然调用重写的实现。
- 通过重写方法来模仿超类中方法实现的重用,可以考虑编写super.reproduce()。 然而,这指的是机器的再现实现,甚至可能不存在。
所以似乎没有办法在默认方法中重用代码来覆盖。 真的是这样吗?
实际上,您可以自由选择现有的实现。 让我给你一个比你更复杂的场景。 更糟糕的是,所有A
, B
和C
都有相同的方法签名。
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"); } }
现在,我创建了一个实现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 } }
输出将是:
Default implementation From A Default implementation From B Default implementation From C
当你跑 :
new Tester().doWork();
HumanoidForm.super.reproduce();
看看这个: https : //blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/
特别是它所说的“如果我们想在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"); } }
所以似乎没有办法在默认方法中重用代码来覆盖。 真的是这样吗?
不,您可以重用代码。 您可以轻松地测试它,您将看到以下代码有效:
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:
From default interface From implementing class