Deadly Diamond of Death...

Its unpredictable for me to choose...

Suppose we have four classes, ClassA. ClassB, ClassC, ClassD. ClassA is abstract and has an abstract method doGood(); ClassB and ClassC extends ClassA. So they must override doGood();
now comes ClassD in picture which extends both ClassB and ClassC. Now, it does not have to override doGood() cause it s already overridden by parent classes. Again ClassD has another method doEvil() which invokes doGood(). Which doGood() version will it invoke, ClassB version or ClassC version ?

Suppose Java supports multiple inheritance through classes, find the output of the following program


 abstract class A {  
      static int counter = 0;  
      public abstract void doGood();  
      public abstract void changeCounter(int value);  
 }  
 class B extends A {  
      @Override  
      public void doGood() {  
           changeCounter(5);  
      }  
      @Override  
      public void changeCounter(int value) {  
           counter = value;  
      }  
 }  
 class C extends A {  
      @Override  
      public void doGood() {  
           changeCounter(15);  
      }  
      @Override  
      public void changeCounter(int value) {  
           counter = value;  
      }  
 }  
 class D extends B, C {  
      public void doEvil() {  
           doGood();  
           System.out.println("Counter is: " + counter);  
      }  
 }  

Can you determine the output ?
No. Its not possible to determine.

The pictorial form is like below,


This is knows as Deadly Diamond of Death. Java avoids this situation by providing multiple inheritance only through Interfaces where the implementing class must override the methods of Interface and as only a class is supported to be extended so, no problem if you extend a class overriding the Interface. So, if you try to create a situation of Deadly Diamond of Death, Java simply won't allow you.

Check the following, it has no problem though it supports multiple inheritance.

 interface A {  
      public void doGood();  
      public void doA();  
 }  
 interface B {  
      public void doGood();  
      public void doB();  
 }  
 class C implements A, B {  
      @Override  
      public void doB() {  
           // TODO Auto-generated method stub  
      }  
      @Override  
      public void doGood() {  
           // TODO Auto-generated method stub  
      }  
      @Override  
      public void doA() {  
           // TODO Auto-generated method stub  
      }  
 }  

Even the following is also supported.

 interface A {  
      // Method must be overridden  
      void doGood();  
 }  
 class B implements A {  
      // A introduced new method  
      public void doStuff() {  
           System.out.println("Doing stuffs for A");  
      }  
      // Implementing class must override doGood()  
      @Override  
      public void doGood() {  
           System.out.println("Doing good in B");  
      }  
 }  
 class C extends B implements A {  
      // C introduced another new method  
      public void doMore() {  
           System.out.println("Doing more for C");  
      }  
      // Invoke doGood. No problem, only one implementation is there  
      public void doEvil() {  
           System.out.println("Trying to do evil in C but Java does not allow me to do");  
           doGood();  
      }  
 }  
 public class ABC {  
      public static void main(String args[]) {  
           // Create new object of C  
           C c = new C();  
           // Invoke any method of A, B and C. Inheritance is there in place and  
           // you avoid Deadly Death of Diamond  
           c.doGood();  
           c.doEvil();  
           c.doStuff();  
           c.doMore();  
      }  
 }  

Output is:
 Doing good in B  
 Trying to do evil in C but Java does not allow me to do  
 Doing good in B  
 Doing stuffs for A  
 Doing more for C  

Hope this clears your confusion why Java does not support multiple inheritance through Classes. Comments are always welcome...

Prev
Palash Kanti Kundu
Palash Kanti Kundu

No comments:

Post a Comment