views:

799

answers:

4

Why is multiple inheritance considered to be evil while implementing multiple interfaces is not? Especially when once considers that interfaces are simply pure abstract classes?

(More or less) duplicate of What is the exact problem with multiple inheritance?, Multiple Inheritance in C#, and some others...

+2  A: 

How do you reconcile if A implements a method called z and b implements a method called z and you have:

child : a, b

now if my client code calls new child().z(). Which implementation is being called? I don't think its so much as that its evil it just raises a whole lot of sticky points and provides little value

JoshBerke
+18  A: 

The common problem with multiple inheritance is the "diamond problem".

  A
 / \
B   c
 \ /
  D

If a virtual method in A is implemented by both B and C, which one do you get when you create D?

The reason this isn't a problem with interfaces is because interfaces don't have implementations, so if A/B/C are all interfaces, then D chooses how to implement the A methods in whatever manner is appropriate.

Brad Wilson
+3  A: 

MI is not so much evil as a highly complex solution to a rare problem. In most cases there is a better way to get the same thing done.

BCS
+10  A: 

It's perceived to be evil because it's just more complex and raises more issues than people typically expect, especially where base classes are not purely abstract (no data members). Diamond inheritance can be solved using virtual inheritance, where a common base is shared. And compilers can catch method signature collisions. Used well, it can produce elegant and DRY solutions that are otherwise more verbose to implement via interface and compositions/delegations.

One common MI idiom in C++ is for complex wrapper constructors where base contructor needs to be constructed with non-trivial member objects, and since base objects need to be constructed before member objects, the trick is to use MI (the "base from member" idiom.), otherwise you have to use a factory and more steps to do the construction like Java does (Java doesn't have MI for non-interface classes).

Don't be afraid of it and use it when appropriate (though it might take some practice to spot a good fit).

ididak