In an earlier post, I covered one of Java 8's new features - default methods in interfaces. While I did the pros there were some corner cases to be considered when implementing this feature.
Consider that we have an interface A:
The above code will throw a compiler error -
Consider that we have an interface A:
interface A { default String display(String s) { return s.toLowerCase()+"__"; } }Now I have another interface B that extends from A:
interface B extends A { default String display(String s) { return s.toLowerCase()+"%%"; } }It also overrides the method. Now I added a third interface C, that extends from B. Since C extends from both A and B, which implementation of the method display() will C receive ?
public static void main(String[] args) { System.out.println(new C(){}.display("HELLO")); } interface C extends B { //which version will display() execute ? }If I run the main method then the output is as below:
hello%%This makes sense, as B is the closest to C in the chain, and therefore C gets the method implementation provided by B. This is same as the rules seen with class inheritance. Now consider the below scenario:
interface A { default String display(String s) { return s.toLowerCase()+"__"; } } interface B { default String display(String s) { return s.toLowerCase()+"%%"; } } interface C extends A, B { //which version will display() execute ? }This is a multiple inheritance scenario. Both A and B are independent interfaces and C extends both of them. Which version will C inherit now ?
The above code will throw a compiler error -
Duplicate default methods named display with the parameters (String) and (String)
are inherited from the types B and A
The fix to the issue is to tell the compiler which version of the method must C inherit (This is kind of different to what is done in C++ , where we see the scope resolution operator :: or use explicit casting)
interface C extends A, B { @Override default String display(String s) { return A.super.display(s); } }Here we have to override the display() method and delegate the call to one of the interfaces. On running the code now:
hello__This is also a new use case for the super keyword - something that we have only associated with classes till now.
No comments:
Post a Comment