Multiple Inheritance in Java 8 through Interface - ayushmathur94/DirectQuesAns_Prep GitHub Wiki
Multiple Inheritance in Java is nothing but one class extending more than one class. Previous versions of Java(until JDk 7) doesn’t support Multiple Inheritance because it causes a famous problem called “Diamond Problem“ and hence indirectly Multiple Inheritance in Java is achieved using Interfaces. After the introduction of Default Methods in Java 8, even the interfaces can also have the method bodies. Let’s see how the Diamond Problem is prevented in Java 8.
What is Diamond Problem in Java ?
Let’s first see What is Diamond Problem in Java and Why Java doesn’t support Multiple Inheritance
Multiple Inheritance in Java Example class A { public void disp() { System.out.println("A disp() method called"); } } class B extends A { @Override public void disp() { System.out.println("B disp() method called"); } } class C extends A { @Override public void disp() { System.out.println("C disp() method called"); } } public class D extends B,C //Not Supported by Java { public static void main(String args[]) { D d = new D(); d.disp(); // Ambiguity which disp() to call } }
- Class B and Class C inherits Class A and the disp() method of Class A is overridden by both B and C
- Class D inherits both Class B and C (Not Supported by Java), If suppose we need to call the disp() method through the instance of Class D, then the Java compiler will not know which method to call whether disp() method of Class B or Class C. It results in ambiguity
- In order to overcome the above issue, Multiple Inheritance is achieved through Interface. As in Java we can implement more than one java interface.
In Java 8 Interface can also have method definition using Default Methods, then obviously it should also result in ambiguity isn’t it ? Yes, but Java 8 can handle this type of compatible issues. Lets look into the below example.
package com.javainterviewpoint; interface Car { public default void drive() { System.out.println("Car is driving"); } } interface Jeep { public default void drive() { System.out.println("Jeep is driving"); } } public class Vehicle implements Car,Jeep { public static void main(String args[]) { Vehicle v = new Vehicle(); v.drive(); } }
when we try to execute above class, we will be getting the “Unresolved compilation problem”
In Java 8 you cannot implement multiple interfaces having same signature, without explicitly overriding the methods in the child class.
interface Car { public default void drive() { System.out.println("Car is driving"); } } interface Jeep { public default void drive() { System.out.println("Jeep is driving"); } } public class Vehicle implements Car,Jeep { @Override public void drive() { System.out.println("Vehicle is driving"); } public static void main(String args[]) { Vehicle v = new Vehicle(); v.drive(); } }
Output : Vehicle is driving
Using Super Keyword:
It is also possible to call the Parent interface method explicitly from the Child class. Lets take the above scenario if we want to call the Car interface drive() method, we can do that with the help of Super Keyword.
interface Car { public default void drive() { System.out.println("Car is driving"); } } interface Jeep { public default void drive() { System.out.println("Jeep is driving"); } } public class Vehicle implements Car,Jeep { @Override public void drive() { Car.super.drive(); } public static void main(String args[]) { Vehicle v = new Vehicle(); v.drive(); } } Output : Car is driving
Java 8 supports default methods where interfaces can provide a default implementation of methods. And a class can implement two or more interfaces. In case both the implemented interfaces contain default methods with the same method signature, the implementing class should explicitly specify which default method is to be used, or it should override the default method. Example 3: // Java program to demonstrate Multiple Inheritance // through default methods // Interface 1 interface PI1 { // Default method default void show() { // Print statement if method is called // from interface 1 System.out.println("Default PI1"); } } // Interface 2 interface PI2 { // Default method default void show() { // Print statement if method is called // from interface 2 System.out.println("Default PI2"); } } // Main class // Implementation class code class TestClass implements PI1, PI2 { // Overriding default show method public void show() { // Using super keyword to call the show // method of PI1 interface PI1.super.show(); // Using super keyword to call the show // method of PI2 interface PI2.super.show(); } // Mai driver method public static void main(String args[]) { // Creating object of this class in main() method TestClass d = new TestClass(); d.show(); } } Output Default PI1 Default PI2 Note: If we remove the implementation of default method from “TestClass”, we get a compiler error. If there is a diamond through interfaces, then there is no issue if none of the middle interfaces provide implementation of root interface. If they provide implementation, then implementation can be accessed as above using super keyword. Example 4: // Java program to demonstrate How Diamond Problem // Is Handled in case of Default Methods // Interface 1 interface GPI { // Default method default void show() { // Print statement System.out.println("Default GPI"); } } // Interface 2 // Extending the above interface interface PI1 extends GPI { } // Interface 3 // Extending the above interface interface PI2 extends GPI { } // Main class // Implementation class code class TestClass implements PI1, PI2 { // Main driver method public static void main(String args[]) { // Creating object of this class // in main() method TestClass d = new TestClass(); // Now calling the function defined in interface 1 // from whom Interface 2and 3 are deriving d.show(); } } Output Default GPI