Friday, September 01, 2006

Multiple Inheritance is Evil/Bad...NOT!!!

The Mynx language has 3-types of inheritance:

The 0th element is, strictly speaking, not a type of inheritance, but it is an option for a class, so is included to be consistent and complete.
  1. nothing or null inheritance (class is standalone like C++ no required super-class like C# or Java)

  2. single inheritance

  3. virtual inheritance (inherit multiple virtual classes, like inheriting multiple interfaces in C# or Java)

  4. multiple inheritance
Gasp! Mynx uses multiple inheritance--which is supposed to be "evil" or "bad".

Multiple inheritance is often taught as bad, evil, or somehow a negative thing in the world of object-oriented programming. C++ has (infamously) supported multiple inheritance, as do other languages such as Eiffel, and Python.

Mynx has multiple inheritance, but it has a different kind of multiple inheritance to avoid some of the problematic aspects that come with multiple inheritance.

Name Ambiguity

In C++ multiple inheritance, an aspect of multiple inheritance that can be problematic is name ambiguity; a method is multiply inherited so there is ambiguity in which one to invoke by a name. In C++ the code for name ambiguity is:

class A { virtual void f(); };
class B { virtual void f(); };
class C : A , B { virtual void f(); };

int main()
{
     C* c_ptr = new C;

     c_ptr->f(); //which f() is invoked?

     return 0;
}

The name ambiguity is which method f() is invoked in the call in the main() method.

Deadly Diamond

The classic problem of multiple inheritance is the diamond problem or the "deadly diamond"...when a class inherits from multiple classes with a common ancestor or super-class. This can lead to name ambiguity (as illustrated without the deadly diamond).

In C++, the code for multiple inheritance that creates the deadly diamond is:

class A { virtual void f(); };
class B : A { virtual void f(); };
class C : A { virtual void f(); };
class D : B, C { virtual void f(); };

int main()
{
     D* d_ptr = new D;

     d_ptr->f(); //d_ptr has two instances of class A

     return 0;
}

The problem is that the deadly diamond is repeated inheritance the base class A is inherited multiple times. This can lead to erratic or unpredictable behavior of any class D object instances.

So two "gotchas" that are the difficult aspects of multiple inheritance are:
  1. Name Ambiguity
  2. Repeated Inheritance
C++ (and this is one reason you either love the language or hate it...) has a mechanism to avoid the problems of multiple inheritance, but if a software developer is not careful it is easy to blunder badly. C++ has what I like to term "unrestricted" multiple inheritance...it is up to the class designer to be sure they know what they're doing...and given the bad reputation of multiple inheritance, that takes a great deal of skill and work. (Another reason to hate or love C++...either sink or swim in the language...)

Two other languages have multiple inheritance, including Eiffel, and Python. Both put constraints on the level of multiple inheritance.

Eiffel requires a multiple inherited class to select which one to use. Python uses a depth-first left to right to search for name resolution -- but Python supports only a limited form of multiple inheritance.

Multiple inheritance is so fraught with danger, why does Mynx include it as one of the language features? Simple, Mynx is not trying to constrain the software developer's choices, and multiple inheritance can be useful at times...like an esoteric tool that is infrequently used, you really are glad to have it when the need arises...and as a language designer, I can not foresee that such a need would never arise. Mynx implements multiple inheritance differently...but I'll discuss that in another blog entry.

For those who fear or contend multiple inheritance is evil or bad, the answer is to simply don't use it if you think it is evil...(remember the classic doctor joke? Doctor it hurts when I do this...The doctor says--then don't do it...nyuck...nyuck...) and remember that evil spelled backward is "live"...multiple inheritance in the eye of the beholder...but as the language designer I leave the choice to the Mynx developer using the language.
Website Spy Software