Java 8-Two interfaces contain default methods with the same method signature, but different return types, how to override?

I understand that if a class implements several interfaces containing default methods of the same name, then we must override this method in the child class to explicitly determine what my method will do.
The problem is this: code:

interface A { default void print() { System.out.println(" In interface A "); } } interface B { default String print() { return "In interface B"; } } public class C implements A, B { @Override public String print() { return "In class C"; } public static void main(String arg[]) { // Other funny things } } 

Now interface A and B have a default method named "print", but I want to override the printing method of interface B - the one that returns the string, and leave A print as is. But this code does not compile if:

 Overrides A.print The return type is incompatible with A.print() 

Obviously, the compiler is trying to override the printing method, and I have no idea why!

+5
source share
1 answer

It's impossible.

8.4.8.3 :

If the declaration of method d 1 with return type R 1 overrides or hides the declaration of another method d 2 with return type R 2 , then d 1 must be return-type-substitutable for d 2 , or a compile-time error occurs.

8.4.5 :

Declaring a method d 1 with a return type R 1 is a return type-replaceable for another method d 2 with a return type R 2 if any of the following conditions are true:

  • If R 1 is void , then R 2 is void .

  • If R 1 is a primitive type, then R 2 is identical to R 1 .

  • If R 1 is a reference type, then one of the following conditions is true:

    • R 1 adapted to type d 2 parameters is a subtype of R 2 .

    • R 1 can be converted to a subtype of R 2 by an unverified conversion.

    • d 1 does not have the same signature as d 2 and R 1 = |R 2 | .

In other words, void , primitive and referential return methods can be redefined and redefined using methods of the same corresponding category. The void method can only override another void method, the link return method can only override another link return method, etc.

One possible solution to the problem you have may be to use composition instead of inheritance:

 class C { private A a = ...; private B b = ...; public A getA() { return a; } public B getB() { return b; } } 
+3
source

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


All Articles