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.
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.