Resolving Conflicts During Multiple Inheritance in Java
A class can implement multiple interfaces in java, but what if the implemented multiple default interfaces have default methods with the same signatures? Then in the implementing class, which of the default implementations would be invoked from the several parent interfaces.
Java 8 designers have been thinking about this conflict and have specified rules of resolution for such scenarios. Let us now look at the potential conflict scenarios and the rules of resolution developed into Java 8 to avoid them.
Conflict Resolution Rules for inherited default methods in order of precedence are as follows
- Rule 1: Classes take higher precedence than interfaces
- Rule 2: Derived interfaces or sub-interfaces take higher precedence than the interfaces higher-up in the inheritance hierarchy
- Rule 3: In case of Rule 1 and Rule 2 are not able to resolve the conflict then the implementing class has to specifically override and provide a method with the same method definition.
Now let us discuss them one by one to get the internal workflow understanding of the rules.
Rule 1 Classes take higher precedence than interfaces
method of class D
Since Class C inherits default method m1() from interface A, interface B, and superclass C. If the m1() method is invoked in Class C then the implementation in superclass C is executed.
Rule 2 Derived interfaces or sub-interfaces take higher precedence than the interfaces higher-up in the inheritance hierarchy
m1 method of B
Since interface B inherits from interface A. Both have a default method m1() with the same signature. Class C implements both interfaces A & B. When m1() method is invoked on an instance of class C then the implementation in interface B is invoked as it is the lowest child/most derived interface in the inheritance hierarchy.
Rule 3 In case Rule 1 and Rule 2 are not able to resolve the conflict then the implementing class has to specifically override and provide a method with the same method definition
m1 method of interface B
- To get the desired behavior, the implementing class can, of course, invoke the specific default method from the specific parent interface. But the class still needs to override the default method to resolve the conflict and invoke it.
- Class C inherits from the interfaces A & B in the above example, all of which have the default m1() implementations (). As all A & B interfaces are parents of C, they are at the same level of the hierarchy, and C must also implement the m1() method on its own ().
Note: Inside Class C’s implementation of print() method it should invoke the specific implementation of interface A or B. For this Java 8 has a special syntax as follows:<super-interface-name>.super<method-name>
In this case m1() method in class C will invoke m1() method of B, its parent, like this – B.super.m1()