Tuesday, 27 June 2017

Why no multiple inheritance in Java

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 and hybrid inheritance. Out of these Java does not support multiple inheritance and that is the subject of this post.

Multiple inheritance 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. Though you can still implement several interfaces.

As example if there are three classes - ClassA, ClassB and ClassC. Then -

public class ClassA extends ClassB, 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 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 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.

Example code

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 in Java 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 when MyClass is implementing both interfaces MyInterface1 and MyInterface2 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 Exp. 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.

Example code

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.

Example code

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!


Related Topics

  1. Encapsulation in Java
  2. Polymorphism in Java
  3. Abstraction in Java
  4. Inheritance in Java
  5. interface static methods in Java 8

You may also like -

>>>Go to Java Basics page

1 comment:


  1. Really Good blog post.provided a helpful information about why there is no multiple inheritance in java diamond problem.keep updating...
    Digital marketing company in Chennai

    ReplyDelete