Open In App

Resolving Conflicts During Multiple Inheritance in Java

Improve
Improve
Like Article
Like
Save
Share
Report

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. 

Implementation:

Rule 1  Classes take higher precedence than interfaces 

Example 

Java




// Java Program to illustrate
// classes take higher precedence than interfaces
 
// Importing input output classes
import java.io.*;
 
// Interface 1
interface A {
    public default void m1()
    {
        System.out.println("m1 method of interface m1");
    }
}
 
// Interface 2
interface B {
    public default void m1()
    {
        System.out.println("m1 method of interface B");
    }
}
 
// Helper class
class D {
 
    // Main driver method
    public void m1()
    {
 
        // Print statement when m1() of classD is called
        System.out.println("method of class D");
    }
}
 
// Main class
// It is implementing both the interfaces A and B
class C extends D implements A, B {
 
    // Main driver method
    public static void main(String args[])
    {
        // Creating an object of this class
        // in the mai() method
        C c = new C();
 
        // Calling the method over the object created
        // to illustrate Classes take higher precedence
        // than interfaces
        c.m1();
    }
}


Output:

method of class D

Output explanation:

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

Example

Java




// Java Program to illustrate Derived interfaces or
// sub-interfaces take higher precedence than the interfaces
// higher-up in the inheritance hierarchy
 
// Interface 1
interface A {
 
    // Method of Interface 1
    public default void m1()
    {
 
        // Execution command whenever
        // interface 1 is called
        System.out.println("m1 method of A");
    }
}
 
// Interface 2
// This interface is extending above interface
interface B extends A {
 
    // Method of Interface 1
    public default void m1()
    {
 
        // Execution command whenever
        // interface 2 is called
        System.out.println("m1 method of B");
    }
}
 
// Main class
// Which is implementing Interface 2
class C implements B {
 
    // Main driver method
    public static void main(String args[])
    {
        // Creating an object of this class
        // in the main method
        C c = new C();
 
        // Calling method over class object
        // created above to illustrate sub-interface
        // has higher precedence
        c.m1();
    }
}


Output

m1 method of B

Output explanation:

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

Example 

Java




// Java Program to in which implementing class
// has to specifically override and provide a method
// with the same method definition
// to resolve the conflice
 
// Importing input output classes
import java.io.*;
 
// Interface 1
interface A {
 
    // m1() method of Interface 1/A
    public default void m1()
    {
        System.out.println("m1 method of interface m1");
    }
}
 
// Interface 2
interface B {
 
    // m1() method of Interface 2/B
    public default void m1()
    {
        System.out.println("m1 method of interface B");
    }
}
 
// Main Class
// This class implements both the interfaces
class C implements A, B {
 
    // Method 1
    // m1() method of class C (This class)
    public void m1()
    {
 
        // Super keyword called over m1() method
        // for interface 2/B
        B.super.m1();
    }
 
    // Method 2
    // Main driver method
    public static void main(String args[])
    {
        // Creating an object of this class
        // in the main() method
        C c = new C();
 
        // Calling the method 'm1()'
        // over the class object
        // in the main method()
        c.m1();
    }
}


Output:

m1 method of interface B

Output explanation:

  • 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()



Last Updated : 30 Nov, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads