How to call the default implementation of the default 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 default implementation here? } } 

Now suppose that “the appropriate code for reproducing android” is best described using “appropriate code for reproducing the humanoid form” as a subroutine. How can I access the "corresponding code for the humanoid form" from the "corresponding code for android playback"? I can think of three ways, but none of them work:

  • Just calling the reproduce () function calls an overriding implementation.
  • Writing ((HumanoidForm) this) .reproduce () still causes an override.
  • Imitating the reuse of method implementations in superclasses using overriding methods, you might consider writing super.reproduce (). However, this applies to the implementation of the machine, which may not even exist.

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

+3
source share
4 answers

Actually, you can freely choose an existing implementation. Let me give you a slightly more complex scenario than yours. To make things worse, all A , B and C have the same method signature.

 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 of C that implements A and B:

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

The output will look like this:

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

when you run :

 new Tester().doWork(); 
+2
source
 HumanoidForm.super.reproduce(); 
+4
source

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

In particular, the section that says: "If we want to specifically call one of the sayHi () methods on InterfaceA or InterfaceB, we can also do the following:"

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

So it seems that there is no way to reuse the code in the default method for overriding. Is this 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:

 From default interface From implementing class 
+1
source

Source: https://habr.com/ru/post/1233952/


All Articles