Saturday, July 31, 2021

Why multiple inheritances are not supported in Java

Why multiple inheritence is not supported implemented in javaRecently one of my friends appeared for an interview and after few so-called easy questions, he was asked "Why multiple inheritance is not supported in Java", though he has a brief idea that in Java we can support multiple inheritance in java via interface but the interviewer was kept pressing on why part, maybe he was just read any blog post about it :). So after the interview, my friend comes to me and in a usual talk, he told me about these questions and ask me the answer. 

Well, this is a very classical question like Why String is immutable in Java; the similarity between these two questions is they are mainly driven by design decisions taken by java's creator or designer. Though following two reasons make sense to me on Why Java doesn't support multiple inheritances:


Why Java doesn't support multiple inheritance

1) First reason is ambiguity around the Diamond problem, consider a class A has foo() method and then B and C derived from A and has their own foo() implementation, and now class D derives from B and C using multiple inheritance and if we refer just foo() compiler will not be able to decide which foo() it should invoke. 

This is also called the Diamond problem because the structure on this inheritance scenario is similar to 4 edge diamond, see below

           A foo()
           / \
          /   \
   foo() B     C foo()
          \   /
           \ /
            D
           foo()

In my opinion, even if we remove the top head of diamond class A and allow multiple inheritances we will see this problem of ambiguity.



Sometimes if you give this reason to the interviewer he asks if C++ can support multiple inheritances then why not Java. hmmmmm in that case I would try to explain to him the second reason which I have given below that it's not because of technical difficulty but more to maintainable and clearer design was driving factor though this can only be confirmed by any java designer and we can just speculate. Wikipedia link has some good explanation on how different language address problem arises due to diamond problem while using multiple inheritances.


2. Second and more convincing reason to me is that multiple inheritances does complicate the design and creates problem during casting, constructor chaining etc and given that there are not many scenarios on which you need multiple inheritances its wise decision to omit it for the sake of simplicity. 

Also, java avoids this ambiguity by supporting single inheritance with interfaces. Since the interface only has a method declaration and doesn't provide any implementation there will only be just one implementation of a specific method hence there would not be any ambiguity.

Related post:

28 comments :

Anonymous said...

Similar questions "Why multiple inheritance is not possible in java" is asked to me on an interview, will your answer for Why multiple inheritance is not supported in java , applicable for my questions also ?

mani said...

i think ambiguity is not a reason for that java doesn't support multiple inheritance because in C++ there is a solution for ambiguity........

Anonymous said...

He guys. multiple inheritance IS supported in Java!

You have to be more precies. It is not supported for classes, it is supported for interfaces.

maruti said...

Re: multiple inheritance Vs interface?

The following are the examples
First one uses the classes and the second one uses Interfaces
/***********************Using Classes*************/
class A
{
public void methodAClassA()
{
System.out.println("In ClassA MethodA");
}
}
class B extends A{
public void methodAClassA(){
System.out.print("in Class B Method ClassA");
}
}
class C extends A,B {
/*
* Which is not possible bcoz
* if u use the above code the compiler does not
* know which instace method could be used in the class C
* So they made it as error it will show the compilation error
*
*/
}
/******************Using Interfaces*******************/
interface A
{
public void methodAClassA();

}
interface B extends A{
public void methodAClassA();
}
class C implements A,B {
/*
* Which is possible bcoz
* if we use the above code there is no need of the
* knowing which method instace could be used
* so that the diamond problem doesnot occured
*/
}


I think now its clear how we achieve multiple inheritance in java.....

Michael said...

This interview question is absolutely worthless in determining if someone is a good java programmer. It is nothing more than trivia.

Anonymous said...

Hi Dude as i Know Multiple Inheritence is not supported in java just because of the Violation of super() keyword.
When Ever you called the method/constructor of super class at that time JVm got confused,it cant decide which method you are calling.its something similar to Diamond problem.

And if you need any more help please ask me at
ziaur18@gmail.com.

himayat zehgeer said...

is the definition of the multiple inheritance here enough

Anonymous said...

While both of above reasons are correct to a certain extent, the primary reason is that with inheritance, the inherited class is loaded in the memory each time it's child class object is created. If a class inherited multiple other classes, the memory and load time overhead would get out of control. Which certainly happens in poorly designed C++ applications

An interface implementation is bare bones of a design. More so a restriction upon the child class. With multiple interfaces, only the parts needed by the child class are ever put into it. So the child class can inherit "design restrictions" from multiple classes without any extra overhead at all.

Anonymous said...

Awesome post, thanks! your post combined with this post:

www.programmerinterview.com/index.php/java-questions/multiple-inheritance/

really helped my understanding of multiple inheritance

Gopal said...

Multiple Inheritance for classes is not supported in Java, but it does support multiple inheritance for interfaces. Main reason for not allowing multiple inheritance for classes is Deadly diamond of Death pattern( also known as DDD). As shown above, if class D class a method defined in both B and C, there is no way to identify which one to call, until a fully qualified name is used. Interface doesn't face problem of deadly diamond because they doesn't contain any behavior, behaviors are only defined in classes, all interface method is abstract, which means calling anyone has same effect. I remember, true reason for not supporting multiple inheritance is not technical difficulty but a thoughtful decision taken by Java community to avoid messy code, probably due to deadly diamond pattern.

toufeeq khan said...

multiple inheritance is not supported in java for classes and also for interfaces because the jvm can create only one object at a time.we cannot say that multiple inheritance is supported for interfaces by simply extending more than one interface at a time, forget about the multiple inheritance,that is not even inheritance because inheritance means using the properties of one class into another and we are not using the properties of interfaces, just providing implementations for the abstract methods of the interfaces. also we cannot create objects for interfaces...

Anonymous said...

This is true that the diamond problem comes into play when the multiple inheritance is supported but there's a way around to assign a precedence. For example, in case of a conflict class A will have precedence over class B. But, the efforts required to implement this doesn't justify with the benefits will be achieved through multiple inheritance.

Take an example of source control that supports multiple checkouts. In case of a conflict there's a mechanism of conflict resolution. As it justifies the utility of this feature thus it's supported.

Hope it helps!!!

Regards,
-Mateen.

Unknown said...

HI Guys can you give me the solution ??
Public static void mail(string args[])throws Exception................why we are using throws Exception

Anonymous said...

Why we use final keyword in java?

Anonymous said...

Because somewhere within your mail method you have a call to a method that may throw a checked exception. Java says that when a checked exception may be thrown from within a method call the client(caller) must be made aware of this via the throws keyword on the method signature.

This gives the client 2 options
1 handle the exception by catching it and dealing with it or

2 throwing it up the stack to a higher level that may catch it and handle it. If no method catches it it will propagate all the way to your main method and the program will exit with a stacktrace.

You are doing option 2.

Anonymous said...

final Class
Cannot be extended. This is used for security and to ensure the design of a fundamental class cannot be altered

final method
Cannot be overriden in a subclass

final var
Cannot be changed once assigned.
To enforce an immutable reference

Anonymous said...

When you try to implement 2 interfaces and if both have same methods we implement them using explicit implementation like Disposable1.dispose(){ implementation goes here } then why cant we do the same with classes. Why cant we just call the particular method using Class. I am not saying to use dot operator because it is used for Static methods. Why cant we use a colon something like this

Class A(

public void something()
{
}
}

Class B(

public void something()
{
}
}

public Class C extends A,B
{

A:something();
B:something();
}


What is the problem with this approach as we r doing the same with interfaces.

Anonymous said...

Precisely, Java does support multiple inheritance, what is not supported is "multiple inheritance of state", which is bad and it's great Java doesn't go to that part. Multiple inheritance of Type is supported from start using interfaces, which means your interface can extend more than one interface and thus become polymorphically more powerful. From Java 8 onwards, Java has also started supporting multiple inheritance of behavior using default methods. So, you can only say that Mulitple inheritance of State is not supported in Java, that's it.

Unknown said...

please tell me deference b/w extends and implements in java

Unknown said...

can anyone tell me what is the use of marker interface if it doesn't have any method??

Unknown said...

In interface code,
Which interface method is going to be override.

Anonymous said...

Marker interface doesn't have any method it's achieve only by implementing the interface.its provide speciality to the class. for eg.serializable is marker interface when we implement this interface the state of object is converted into file means in byte code so we can send over the network.its provide security.

Arpit Mandliya said...

Thanks for sharing such useful information on why Multiple Inheritance is not supported by Java. It is one of the frequently asked question s in interviews. You gave correct answer to this question. I agree with your answer that Multiple Inheritance creates ambiguity around Diamond problem. But in Java, We can achieve Multiple Inheritance through the Interface. I have a blog (Java2Blog) which provides more useful Java interview questions and answers. And also provides complete tutorial on Java.

javin paul said...

Hello Arpit, I know your blog, you are doing good job, keep it up, nice to see you here :-)

Anonymous said...

Hi Javin,

With the default method feature in java 8, one can provide the concrete implementation in interface itself. So i don't think so this question is valid anymore.

Anonymous said...

Obviously yaar..both r same question

Giuseppe Ficara said...

"With the default method feature in java 8, one can provide the concrete implementation in interface itself. So i don't think so this question is valid anymore."

Well... that is technically false. The default method defined in an interface is used ONLY if no other implementation is provided. In case a method with the same signature of the default one is provided, this "takes precedence". EVEN IN THE CASE THIS METHOD IS INHERITED by another class.
A simple test can help understand. Suppose that the following classes and interface are provided:


public class A {

public void a() {
System.out.println("This is the method a() in class A");
}

public static void main(String[] args) {
System.out.println("This is the method main() in class A");
A a=new A();
a.a();
}

}

-----------

public interface B {
public default void a() {
System.out.println("This is the method a() in interface B");
}
}

-----------

public class C extends A implements B {

public static void main(String[] args) {
System.out.println("This is the method main() in class C");
C c=new C();
c.a();
}

}

-----------

Class A and interface B define the method a() with the same signature. In this case, when class C is defined extending class A and implementing class B, there's the method a() that clashes. The compliler though, doesn't signal any error. In fact it compiles correctly and the execution, as expected returns the following:

This is the method main() in class C
This is the method a() in class A

Let add a bit of code:


public interface D {
public default void a() {
System.out.println("This is the method a() in interface D");
}
}

-----------

public class E /* * extends A /* */ implements B, D{

public static void main(String[] args) {
System.out.println("This is the method main() in class E");
E e=new E();
e.a();
}

}

Note that Class E DOESN'T implement class A (since that part of code is commented). In this case, the compiler refuses to do it's job: "Duplicate default methods named a with parameters () and () are inherited from types D and B". In other terms, default methods with the same signature cannot be inherited from two interfaces, without being explicitly implemented: the class cannot be compiled.

If we add a "/", right after the second "*" of the class declaration (i.e. if we uncomment the "extends A" bit...) so that we have

public class E /* */ extends A /* */ implements B, D{

public static void main(String[] args) {
System.out.println("This is the method main() in class E");
E e=new E();
e.a();
}

}

...not only the class compiles, but behaves as expected:

This is the method main() in class E
This is the method a() in class A

Which proves the point: there's no "diamond problem" since the explicit implementation of a method in a class, even in an ancestor class, takes precedence (i.e. prevales) over the default implementation of any interface, interface implementation that is completely ignored.

Anonymous said...

Nice explanation

Post a Comment