Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the diamond case with its common ancestor used to explain Java multiple inheritance issue, instead of two unrelated parent classes?

This question might sound weird to Java people but if you try to explain this, it would be great.

In these days I am clearing some of Java's very basic concept. So I come to Inheritance and Interface topic of Java.

While reading this I found that Java does not support Multiple Inheritance and also understood that, what I am not able to understand that why everywhere Diamond figure issue(At least 4 class to create diamond) is discussed to explain this behavior, Can't we understand this issue using 3 classes only.

Say, I have class A and class B, these two classes are different (they are not child class of common class) but they have one common method and they look like :-

class A {     void add(int a, int b) {      } }  class B {     void add(int a, int b) {      } } 

Ok,Now say if Java supports Multiple inheritance and if there is one class which is the subclass of A and B like this :-

class C extends A,B{ //If this was possible     @Override     void add(int a, int b) {          // TODO Auto-generated method stub         super.add(a, b); //Which version of this, from A or B ?     }  } 

then compiler will not be able to find which method to call whether from A or B and that is why Java does not support Multiple Inheritance. So is there any thing wrong with this concept ?

When I read about this topic I was able to understand Diamond issue, but I am not able to understand why people are not giving example with three class (If this is valid one, because we used only 3 classes to demonstrate issue so its easy to understand by comparing it to Diamond issue.)

Let me know whether this example does not fit to explain issue or this can also be referred to understand issue.

Edit: I got one close vote here stating that question is not clear. Here is main question :-

Can I understand Why "Java does not support Multiple Inheritance" with 3 classes only as described above or I must need to have 4 classes (Diamond structure) to understand the issue.

like image 622
Roshan Jha Avatar asked Oct 13 '14 11:10

Roshan Jha


People also ask

Why does Java not support multiple inheritance explain the diamond problem?

But remember that Java does not support the multiple inheritance because of the diamond problem. As simple inheritance allows a child class to derive properties from one super-class. for example, if class B inherits properties from only one super-class A, then it is called simple inheritance, and Java supports them.

Why does diamond problem arise due to multiple inheritance?

Explanation: The diamond problem arises when multiple inheritance is used. This problem arises because the same name member functions get derived into a single class. Which in turn creates ambiguity in calling those methods.

What is a diamond problem in multiple inheritance and how we can solve it?

The Diamond Problem is fixed using virtual inheritance, in which the virtual keyword is used when parent classes inherit from a shared grandparent class. By doing so, only one copy of the grandparent class is made, and the object construction of the grandparent class is done by the child class.

How does Java overcome the diamond problem of multiple inheritance using interfaces?

Java doesn't support multiple inheritance, so the diamond problem doesn't arise. If B & C are interfaces, then there is no implementation in the interfaces. Even if B & C override the method in interface A (cannot be a class), the methods will have same signature.


2 Answers

The problem with diamond inheritance is not so much shared behaviour but shared state. As you can see, Java in fact has always supported multiple inheritance, but only multiple inheritance of type.

With only three classes the problem is resolved relatively easily by introducing a simple construct like super.A or super.B. And while you're only looking at overridden methods, it indeed doesn't matter whether you have a common ancestor or just the basic three classes.

However if A and B have a common ancestor, the state of which they both inherit, then you're in serious trouble. Do you store two separate copies of the state of this common ancestor? That would be more like composition than inheritance. Or do you only store one that is shared by both A and B, causing strange interactions when they manipulate their inherited shared state?

class A {   protected int foo; }  class B extends A {   public B() {     this.foo = 42;   } }  class C extends A {   public C() {     this.foo = 0xf00;   } }  class D extends B,C {   public D() {     System.out.println( "Foo is: "+foo ); //Now what?   } } 

Note how the above wouldn't be so big a problem if class A didn't exist and both B and C declared their own foo field. There would still be a problem of clashing names, but that could be resolved with some namespacing construct (B.this.foo and C.this.foo maybe, as we do with inner classes?). The true diamond problem on the other hand is more than a naming clash, it's a matter of how to maintain class invariants when two unrelated superclasses of D (B and C) share the same state they both inherit from A. This is why all four classes are needed to demonstrate the full extent of the problem.

Shared behaviour in multiple inheritance doesn't exhibit the same problem. So much so that the recently introduced default methods do exactly that. This means that multiple inheritance of implementations is allowed now too. There is still some complication around the resolution of which implementation to call but since interfaces are stateless, the biggest bugbear is avoided.

like image 176
biziclop Avatar answered Oct 18 '22 17:10

biziclop


Java does not support multiple inheritance because the designers of the language designed Java this way. Other languages like C++ support multiple inheritance just fine, so it is not a technical issue but just a design criteria.

The problem with multiple inheritance is that it is not always clear which method from which class you are calling to, and which instance variables you are accessing to. Different people interpret it differently and the Java designers believed at that time that it was better to skip multiple inheritance altogether.

C++ solves the diamond shaped class issue with virtual inheritance:

Virtual inheritance is a technique used in object-oriented programming, where a particular base class in an inheritance hierarchy is declared to share its member data instances with any other inclusions of that same base in further derived classes. For example, if class A is normally (non-virtually) derived from class X (assumed to contain data members), and class B likewise, and class C inherits from both classes A and B, it will contain two sets of the data members associated with class X (accessible independently, often with suitable disambiguating qualifiers). But if class A is virtually derived from class X instead, then objects of class C will contain only one set of the data members from class X. The best-known language that implements this feature is C++.

Contrary to Java, in C++ you can disambiguate which instance method to call by prefixing the call with the name of the class:

class X {   public: virtual void f() {     }  };  class Y : public X {   public: virtual void f() {     }  };  class Z : public Y {   public: virtual void f() {      X::f();   }  }; 
like image 28
vz0 Avatar answered Oct 18 '22 17:10

vz0