Inheritance is one of the four fundamental OOP concepts. It can be defined as a mechanism, by which one class acquires, all the properties and behaviors of another class. Java being an object oriented language does support inheritance. Though with in inheritance there are several types like-
- Single inheritance
- Multi-level inheritance
- Multiple inheritance
- Hierarchical inheritance
- Hybrid inheritance
Out of these Java does not support multiple inheritance, in this post we'll see why multiple inheritance is not supported in Java.
Multiple inheritance support in Java
Multiple inheritance as the name suggests means inheriting from multiple sources, it may be classes or interfaces.
Out of these two sources Java doesn’t support multiple inheritance through classes. So you are not permitted to extend more than one class in Java. Though you can still implement several interfaces.
For example, if there are three classes- ClassA
, ClassB
and ClassC
. Then-
public class ClassA extends ClassB, ClassC
Where ClassA is trying to extend multiple classes; ClassB and ClassC is not permitted in Java.
At the same time-
public class ClassA implements InterfaceB, InterfaceC
where InterfaceB
and InterfaceC
are interfaces that are implemented by the classA is permitted.
Why no multiple inheritance in Java through classes
Multiple inheritance by extending several classes is one feature omitted in the Java language as the designers of the Java language opined that multiple inheritance is a confusing feature and it causes more problems than it solves.
One of the reason given for omitting multiple inheritance in Java is to avoid “diamond problem” which is one of the classic multiple inheritance problem.
Multiple inheritance and Diamond problem
It is best to explain diamond problem with an example so let’s take an example where we have 4 classes. On top of the hierarchy is ClassA which is extended by two classes ClassB and ClassC and there is another class ClassD which extends both ClassB and ClassC. Because of the diamond shaped class structure it is known as diamond problem.
Let’s assume in ClassA there is a method displayGreeting() which is inherited by ClassB and ClassC and they both override it and provide their own implementation of the displayGreeting() method. When ClassD extends both classes ClassB and ClassC there is an ambiguity. Which displayGreeting() method should it inherit or override.
So the ambiguity which multiple inheritance can bring in to parent-child class structure is one reason multiple inheritance is omitted in Java.
Multiple inheritance with interfaces
Java does allow multiple inheritance using several interfaces if not by extending several classes. Though a proper term would be multiple implementation not multiple inheritance as a class implementing interfaces is responsible for providing implementation.
Multiple Inheritance with Interfaces Java Example
There are two interfaces MyInterface1 and MyInterface2 with a method displayGreeting(), there is also a class MyClass which implements both these interfaces. With interfaces, even if there is a similar method in both the interfaces there is no ambiguity as the class that implements provide the implementation.
public interface MyInterface1 { public void displayGreeting(String msg); }
public interface MyInterface2 { public void displayGreeting(String msg); }
public class MyClass implements MyInterface1, MyInterface2{ public static void main(String[] args) { MyClass myClass = new MyClass(); MyInterface1 myInt1 = myClass; MyInterface2 myInt2 = myClass; myInt1.displayGreeting("Welcome"); myInt2.displayGreeting("Hello"); } @Override public void displayGreeting(String msg) { System.out.println(msg); } }
Output
Welcome Hello
Back to multiple inheritance ambiguity with default interfaces
In Java 8, interface default methods are added and the inclusion of default methods interfaces may result in multiple inheritance issues.
Let's see it with an example-
Let's assume there are two interfaces MyInterface1
and MyInterface2
and both have default method
displayGreeting()
. There is a class MyClass
which implements both these interfaces MyInterface1 and MyInterface2.
Now consider the scenarios-
- Which implementation of default method
displayGreeting()
will be called whenMyClass
is implementing both interfacesMyInterface1
andMyInterface2
and not overriding the displayGreeting() method. - Which implementation of displayGreeting() will be called when MyClass is implementing both interfaces MyInterface1 and MyInterface2 and overriding the displayGreeting() method and providing its own implementation.
- If interface MyInterface1 is inherited by interface MyInterface2, what will happen in that case?
To handle these kinds of scenarios, Java defines a set of rules for resolving default method conflicts.
- When class implements both interfaces and both of them have the same default method, also the class is not overriding
that method then the error will be thrown.
"Duplicate default methods named displayGreeting inherited from the interfaces" - If implementing class overrides the default method and provides its own functionality for the default method then
the method of the class takes priority over the interface default methods.
As Example, if MyClass provides its own implementation of displayGreeting(), then the overridden method will be called not the default method in MyInterface1 or MyInterface2.
- In case when an interface extends another interface and both have the same default method, the inheriting interface default method will take precedence. Thus, if interface MyInterface2 extends MyInterface1 then the default method of MyInterface2 will take precedence.
public interface MyInterface1 { // default method default void displayGreeting(String msg){ System.out.println("MyInterface1 " + msg); } }
public interface MyInterface2 { // default method default void displayGreeting(String msg){ System.out.println("MyInterface2 " + msg); } }
public class MyClass implements MyInterface1, MyInterface2{ public static void main(String[] args) { MyClass myClass = new MyClass(); MyInterface1 myInt1 = myClass; MyInterface2 myInt2 = myClass; myInt1.displayGreeting("Welcome"); myInt2.displayGreeting("Hello"); } @Override public void displayGreeting(String msg) { System.out.println(msg); } }
Output
Welcome Hello
Usage of super with default method
There is one more option to use super in order to call default method. If you want to call the default method of any of the interfaces from the implementing class super can be used to resolve the conflict.
If you use the same class structure as above and you want to call the default displayGreeting() method of the MyInterface1 then it can be done as follows-
public class MyClass implements MyInterface1, MyInterface2{ public static void main(String[] args) { MyClass myClass = new MyClass(); MyInterface1 myInt1 = myClass; myInt1.displayGreeting("Welcome"); /*MyInterface2 myInt2 = myClass; myInt2.displayGreeting("Hello");*/ } @Override public void displayGreeting(String msg) { MyInterface1.super.displayGreeting(msg); } }
That's all for this topic Why no Multiple Inheritance in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Basics Tutorial Page
Related Topics
You may also like-
Very clear explanation.
ReplyDeleteThis is really an amazing explanation and came to know that why java does not support Multiple inheritance…. Keep Posting you are doing a good work…….
very good explanation...... getting interest in reading your posts... thanks
ReplyDelete