Multiple Inheritance in Java

Filed Under: Java

Today we will look into Multiple Inheritance in Java. Sometime back I wrote few posts about inheritance, interface and composition in java. In this post, we will look into java multiple inheritance and then compare composition and inheritance.

Multiple Inheritance in Java

multiple inheritance in java
Multiple inheritance in java is the capability of creating a single class with multiple superclasses. Unlike some other popular object oriented programming languages like C++, java doesn’t provide support for multiple inheritance in classes.

Java doesn’t support multiple inheritances in classes because it can lead to diamond problem and rather than providing some complex way to solve it, there are better ways through which we can achieve the same result as multiple inheritances.

Diamond Problem in Java

To understand diamond problem easily, let’s assume that multiple inheritances were supported in java. In that case, we could have a class hierarchy like below image.

diamond problem in java

Let’s say SuperClass is an abstract class declaring some method and ClassA, ClassB are concrete classes.

SuperClass.java


package com.journaldev.inheritance;

public abstract class SuperClass {

	public abstract void doSomething();
}

ClassA.java


package com.journaldev.inheritance;

public class ClassA extends SuperClass{
	
	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of A");
	}
	
	//ClassA own method
	public void methodA(){
		
	}
}

ClassB.java


package com.journaldev.inheritance;

public class ClassB extends SuperClass{

	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of B");
	}
	
	//ClassB specific method
	public void methodB(){
		
	}
}

Now let’s say ClassC implementation would be something like below and it’s extending both ClassA and ClassB.

ClassC.java


package com.journaldev.inheritance;

// this is just an assumption to explain the diamond problem
//this code won't compile
public class ClassC extends ClassA, ClassB{

	public void test(){
		//calling super class method
		doSomething();
	}

}

Notice that test() method is making a call to superclass doSomething() method. This leads to the ambiguity as the compiler doesn’t know which superclass method to execute. Because of the diamond-shaped class diagram, it’s referred to as Diamond Problem in java. The diamond problem in Java is the main reason java doesn’t support multiple inheritances in classes.

Notice that the above problem with multiple class inheritance can also come with only three classes where all of them has at least one common method.

Multiple Inheritance in Java Interfaces

You might have noticed that I am always saying that multiple inheritances is not supported in classes but it’s supported in interfaces. A single interface can extend multiple interfaces, below is a simple example.

InterfaceA.java


package com.journaldev.inheritance;

public interface InterfaceA {

	public void doSomething();
}

InterfaceB.java


package com.journaldev.inheritance;

public interface InterfaceB {

	public void doSomething();
}

Notice that both the interfaces are declaring the same method, now we can have an interface extending both these interfaces like below.

InterfaceC.java


package com.journaldev.inheritance;

public interface InterfaceC extends InterfaceA, InterfaceB {

	//same method is declared in InterfaceA and InterfaceB both
	public void doSomething();
	
}

This is perfectly fine because the interfaces are only declaring the methods and the actual implementation will be done by concrete classes implementing the interfaces. So there is no possibility of any kind of ambiguity in multiple inheritances in Java interfaces.

That’s why a java class can implement multiple interfaces, something like below example.

InterfacesImpl.java


package com.journaldev.inheritance;

public class InterfacesImpl implements InterfaceA, InterfaceB, InterfaceC {

	@Override
	public void doSomething() {
		System.out.println("doSomething implementation of concrete class");
	}

	public static void main(String[] args) {
		InterfaceA objA = new InterfacesImpl();
		InterfaceB objB = new InterfacesImpl();
		InterfaceC objC = new InterfacesImpl();
		
		//all the method calls below are going to same concrete implementation
		objA.doSomething();
		objB.doSomething();
		objC.doSomething();
	}

}

Did you noticed that every time I am overriding any superclass method or implementing any interface method, I am using @Override annotation. Override annotation is one of the three built-in java annotations and we should always use override annotation when overriding any method.

Composition for the rescue

So what to do if we want to utilize ClassA function methodA() and ClassB function methodB() in ClassC. The solution lies in using composition. Here is a refactored version of ClassC that is using composition to utilize both classes methods and also using doSomething() method from one of the objects.

ClassC.java


package com.journaldev.inheritance;

public class ClassC{

	ClassA objA = new ClassA();
	ClassB objB = new ClassB();
	
	public void test(){
		objA.doSomething();
	}
	
	public void methodA(){
		objA.methodA();
	}
	
	public void methodB(){
		objB.methodB();
	}
}

Composition vs Inheritance

One of the best practices of Java programming is to “favor composition over inheritance”. We will look into some of the aspects favoring this approach.

  1. Suppose we have a superclass and subclass as follows:

    ClassC.java

    
    package com.journaldev.inheritance;
    
    public class ClassC{
    
    	public void methodC(){
    	}
    }
    

    ClassD.java

    
    package com.journaldev.inheritance;
    
    public class ClassD extends ClassC{
    
    	public int test(){
    		return 0;
    	}
    }
    

    The above code compiles and works fine but what if ClassC implementation is changed like below:

    ClassC.java

    
    package com.journaldev.inheritance;
    
    public class ClassC{
    
    	public void methodC(){
    	}
    
    	public void test(){
    	}
    }
    

    Notice that test() method already exists in the subclass but the return type is different. Now the ClassD won’t compile and if you are using any IDE, it will suggest you change the return type in either superclass or subclass.

    Now imagine the situation where we have multiple levels of class inheritance and superclass is not controlled by us. We will have no choice but to change our subclass method signature or its name to remove the compilation error. Also, we will have to make a change in all the places where our subclass method was getting invoked, so inheritance makes our code fragile.

    The above problem will never occur with composition and that makes it more favorable over inheritance.

  2. Another problem with inheritance is that we are exposing all the superclass methods to the client and if our superclass is not properly designed and there are security holes, then even though we take complete care in implementing our class, we get affected by the poor implementation of the superclass.

    Composition helps us in providing controlled access to the superclass methods whereas inheritance doesn’t provide any control of the superclass methods, this is also one of the major advantages of composition over inheritance.

  3. Another benefit with composition is that it provides flexibility in the invocation of methods. Our above implementation of ClassC is not optimal and provides compile-time binding with the method that will be invoked, with minimal change we can make the method invocation flexible and make it dynamic.

    ClassC.java

    
    package com.journaldev.inheritance;
    
    public class ClassC{
    
    	SuperClass obj = null;
    
    	public ClassC(SuperClass o){
    		this.obj = o;
    	}
    	public void test(){
    		obj.doSomething();
    	}
    	
    	public static void main(String args[]){
    		ClassC obj1 = new ClassC(new ClassA());
    		ClassC obj2 = new ClassC(new ClassB());
    		
    		obj1.test();
    		obj2.test();
    	}
    }
    

    Output of above program is:

    
    doSomething implementation of A
    doSomething implementation of B
    

    This flexibility in method invocation is not available in inheritance and boosts the best practice to favor composition over inheritance.

  4. Unit testing is easy in composition because we know what all methods we are using from superclass and we can mock it up for testing whereas in inheritance we depend heavily on superclass and don’t know what all methods of superclass will be used, so we need to test all the methods of superclass, that is an extra work and we need to do it unnecessarily because of inheritance.

That’s all for multiple inheritances in java and a brief look at composition.

Comments

  1. joker says:

    Two interfaces A and B having two same name method or different name methods without any definition. a class C is implementing methods from Interface A and B and giving definitions to those methods and we call it multiple inheritance.
    ????????????? ————- HOW ? ————– ????????????

    interface A
    {
    public void method_A();
    }

    interface B
    {
    public void method_B();
    }

    Class C implements A,B
    {
    public void method_A()
    {
    System.out.println(“does not make any sense”);
    }
    public void method_B()
    {
    System.out.println(“This one too is useless”);
    }

    public void thisone()
    {
    System.out.print(“Both methods method_A() and method_B() can be declared and defined in class C”);
    System.out.println(“then what is the use of interface”);
    }
    }

    Can’t we declare those methods in Class C without any interface.
    If multiple inheritance is not possible in Java then we should not try it, above examples are just misleading the interface concepts, interfaces are used to achieve design pattern problems e.g Adapter pattern.

  2. Victor says:

    Multiple inheritance in Java is possible (although in limited way) since java 8, using default method of the interface

  3. Narendar says:

    Thanks Pankaj,

    Good Explanation….,

  4. shubhada says:

    interface a1
    {
    int a=1;
    }
    interface b1
    {
    int a=2;
    }
    class a implements a1,b1
    {
    print (a)
    }
    what values of a will print in case of multiple inheritance

    1. Pankaj says:

      Error: reference to a is ambiguous…

  5. Surya says:

    The author Pankaj has mentioned assumption:
    To understand diamond problem easily, “let’s assume” that multiple inheritance was supported in java.

    Pankaj is right in trying to explain the concept.

    He already mentioned:
    Java doesn’t support multiple inheritance in classes because it can lead to diamond problem.

    Pankaj can you please assert that there is no diamond problem because java has no multiple inheritance in the first paragraph. So that way now one is carried away.

    Thanks in advance.

  6. Daniel says:

    “ClassC extends ClassA, ClassB” – excuse me? 🙂

    1. Surya says:

      I Agree. Very True. Impossible.
      Java Has NO Diamond problem whatsoever.

      1. Pankaj says:

        Please read the text before the code. This is just to show what can happen if java classes can extend more than one concrete classes.

        1. Surya says:

          Thank you. Now I see what you mean.
          You mentioned:
          “To understand diamond problem easily, let’s assume that multiple inheritance was supported in java.”

          Must have highlighted “let’s assume”. It skips mind easily otherwise.

          Thanks again.

  7. Chandra Shekar Gowda M says:

    Hi everyone the explained multiple inheritance concept is wrong.

    first thing is we cannot extend two classes , there itself we get compile time error.

    the correct answer for “why multiple inheritance is not possible in java ” is.

    every class contains constructor , if user is not defined the constructor compiler itself will define the constructor and internally the super class constructor is called by super() calling statement and we cannot have 2 super() calling statements and when we extend 2 class to one class there will be an ambiguity for sub class constructor that is , for which class it should call. but interface doesn’t contain constructor so it can be achieved through interface.

    1. Pankaj says:

      Hi Chandra,

      I am not sure if you read the complete post, I have clearly mentioned in bold that “Java doesn’t provide support for multiple inheritances in classes.”

      Secondly, I have explained about one of the main reason as being the diamond problem. What you are suggesting with super() also falls in the same category. If creators of Java would have wanted to support multiple inheritances, they would have found some workaround to all these issues. Java by design doesn’t support multiple inheritances with classes, just as some other programming languages support it by design. It was a choice made by the creators of Java and we are just showing the possible reasons to do that.

    2. Anton Milan says:

      I think this is not right at all…. Then what will happen if you explicitly call both the super class constructors….. Even then it’ll not work…. Ross answer is wrong

  8. varsha says:

    how we can achieve composition in abstract class?

    1. Amar Kumar says:

      make the attribute of class Is Private.
      like…

      this is our abstract class
      package com.abstractvthinheritance;

      public abstract class Engine {

      public abstract int startMode(int mode);
      }

      NOTE:– Provide the Implementation of Abstract class

      implementing Composition Code below:-

      package com.abstractvthinheritance;

      public class Car {

      private Engine engine;//Composition

      // which makes our code to testable and we can use at the basis of modularity

      Car(Engine engine){
      this.engine=engine;
      }

      public int drive(int mode) {
      int outCome = 0;

      outCome=engine.startMode(0);
      if (outCome==0) {
      System.out.println(“Accelereate the Car and Drive”);
      }else if (outCome ==1) {
      System.out.println(“Need to Try again “);
      }else if (outCome ==2) {
      System.out.println(“Need Maintenace of Engine “);
      }else if (outCome == 3) {
      System.out.println(“failed to start “);
      }

      return 0;
      }
      }

      This way we can implement Composition

      1. kopid says:

        public class Car missing extends Engine how can it implement Engine ?

  9. Paresh Sojitra says:

    Hi, We can change the access specifier as private test() method of ClassC and we again declare the same method as public in ClassD, It Will compile without error. It’s doesn’t matter return type as well.

    public class ClassC{

    public void methodC()
    {

    }

    private void test()
    {
    }
    }

    public class ClassD extends ClassC {

    public int test()
    {
    return 0;
    }
    }

  10. subrat says:

    sir u do not discuss abstract class before.if u take example like this how student will understand

  11. T sinha says:

    Can you please explain the example given in point 3, public ClassC(SuperClass o){
    this.obj = o;
    }
    .
    .
    .

    ClassC obj1 = new ClassC(new ClassA());
    ClassC obj2 = new ClassC(new ClassB());

    How can this be achived?

  12. Yashvir Singh says:

    You are awesome Pankaj.

  13. Ravi Verma says:

    You are awesome Pankaj.

  14. Mayank says:

    There are many advantages of using composition, couple of them are :

    You will have full control of your implementations. i.e., you can expose only the methods you intend to expose.
    any changes in the super class can be shielded by modifying only in your class. Any clients classes which uses your classes, need not make modifications.
    Allows you to control when you want to load the super class (lazy loading)

  15. Yunus Atheist says:

    composition has its limitations. I believe composition is an option as long as the classes and their methods we want to consume are “public”. In case we want to access “protected” members you have to fall back on either Interfaces or Classes. Not denying – composition is a useful means and improves our code refactoring skills.

  16. safdar says:

    Suppose we have a superclass and subclass as follows:
    ClassC.java
    1
    2
    3
    4
    5
    6
    7
    package com.journaldev.inheritance;

    public class ClassC{

    public void methodC(){
    }
    }
    ClassD.java
    1
    2
    3
    4
    5
    6
    7
    8
    package com.journaldev.inheritance;

    public class ClassD extends ClassC{

    public int test(){
    return 0;
    }
    }
    The above code compiles and works fine but what if ClassC implementation is changed like below:

    ClassC.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package com.journaldev.inheritance;

    public class ClassC{

    public void methodC(){
    }

    public void test(){
    }
    }Suppose we have a superclass and subclass as follows:
    ClassC.java
    1
    2
    3
    4
    5
    6
    7
    package com.journaldev.inheritance;

    public class ClassC{

    public void methodC(){
    }
    }
    ClassD.java
    1
    2
    3
    4
    5
    6
    7
    8
    package com.journaldev.inheritance;

    public class ClassD extends ClassC{

    public int test(){
    return 0;
    }
    }
    The above code compiles and works fine but what if ClassC implementation is changed like below:

    ClassC.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package com.journaldev.inheritance;

    public class ClassC{

    public void methodC(){
    }

    public void test(){
    }
    }

    I think this not the problem after Jdk 1.5 where we can have different return types for both overriding and overidden methods in the parent and subclass.

  17. Sorrowfull Blinger says:

    Can u give examples/Complete class defintions to proove your 2nd & 3rd point of Composition better than inheritance.??

  18. Suman says:

    How the multiple inheritance is possible in C , C++ but not in java
    can u explain the context…

  19. Elumalai says:

    How the multiple inheritance is possible in C , C++ but not in java
    can u explain the context…

    1. Asif Mushtaq says:

      class A{
      void method1(){}
      };
      class B{
      void method2(){}
      };
      class C: public A, public B{

      }

      ////////////////////////////
      Now C have both methods .. method1 and method 2.. that’s multiple inheritance in C++, but java not allowed it.

  20. Madhusmita Nayak says:

    What is association in Java?

  21. subbareddy says:

    good explanation………….

  22. Super Hubo says:

    Bit confused. “favor composition over interfaces” or “favor composition over inheritance”?.

    1. Pankaj says:

      Thanks for catching the typo error, corrected it.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages