Why Is Multiple Inheritance Not Allowed in Java or C#

Why is Multiple Inheritance not allowed in Java or C#?

The short answer is: because the language designers decided not to.

Basically, it seemed that both the .NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexity to the languages while providing too little benefit.

For a more fun and in-depth read, there are some articles available on the web with interviews of some of the language designers. For example, for .NET, Chris Brumme (who worked at MS on the CLR) has explained the reasons why they decided not to:

  1. Different languages actually have different expectations for how MI
    works. For example, how conflicts are
    resolved and whether duplicate bases
    are merged or redundant. Before we can
    implement MI in the CLR, we have to do
    a survey of all the languages, figure
    out the common concepts, and decide
    how to express them in a
    language-neutral manner. We would also
    have to decide whether MI belongs in
    the CLS and what this would mean for
    languages that don't want this concept
    (presumably VB.NET, for example). Of
    course, that's the business we are in
    as a common language runtime, but we
    haven't got around to doing it for MI
    yet.

  2. The number of places where MI is truly appropriate is actually quite
    small. In many cases, multiple
    interface inheritance can get the job
    done instead. In other cases, you may
    be able to use encapsulation and
    delegation. If we were to add a
    slightly different construct, like
    mixins, would that actually be more
    powerful?

  3. Multiple implementation inheritance injects a lot of complexity into the
    implementation. This complexity
    impacts casting, layout, dispatch,
    field access, serialization, identity
    comparisons, verifiability,
    reflection, generics, and probably
    lots of other places.

You can read the full article here.

For Java, you can read this article:

The reasons for omitting multiple
inheritance from the Java language
mostly stem from the "simple, object
oriented, and familiar" goal. As a
simple language, Java's creators
wanted a language that most developers
could grasp without extensive
training. To that end, they worked to
make the language as similar to C++ as
possible (familiar) without carrying
over C++'s unnecessary complexity
(simple).

In the designers' opinion, multiple
inheritance causes more problems and
confusion than it solves. So they cut
multiple inheritance from the language
(just as they cut operator
overloading). The designers' extensive
C++ experience taught them that
multiple inheritance just wasn't worth
the headache.

Why is there no multiple inheritance in Java, but implementing multiple interfaces is allowed?

Because interfaces specify only what the class is doing, not how it is doing it.

The problem with multiple inheritance is that two classes may define different ways of doing the same thing, and the subclass can't choose which one to pick.

Why C# doen't support multiple inheritance

Using interfaces is more flexible and eliminates the ambiguity of multiple inheritance.

Further details, HERE.

Does C# support multiple inheritance 4.0?

They probably meant can a class derive from two or more base classes, which it cannot. Confusing wording.

public abstract class A1;
public abstract class A2;
public abstract class B : A2;
public class C : A1, A2; // invalid
public class D : B; // valid

How did C#'s lack of multiple inheritance lead to the need for interfaces?

An interface is simply a base class that has no data members and only defines public abstract methods. For example, this would be an interface in C++:

class IFrobbable {
public:
virtual void Frob() = 0;
}

Therefore when MI is available as a language feature you can "implement" interfaces by simply deriving from them (again, C++):

class Widget : public IFrobbable, public IBrappable {
// ...
}

Multiple inheritance in the general case gives rise to many questions and problems that don't necessarily have a single answer, or even a good one for your particular definition of "good" (dreaded diamond, anyone?). Multiple interface implementation sidesteps most of these problems exactly because the concept of "inheriting" an interface is a very constrained special case of inheriting a full-blown class.

And this is where "forced us to add the concept of interfaces" comes in: you cannot do much OO design when constrained to single inheritance only, for example there are serious issues with not being able to reuse code when code reuse is in fact one of the most common arguments for OO. You have to do something more, and the next step is adding multiple inheritance but only for classes that satisfy the constraints of an interface.

So, I interpret Krzysztof's quote as saying

Multiple inheritance in the general case is a very thorny problem that
we could not tackle in a satisfactory manner given real-life
constraints on the development of .NET. However, interface inheritance
is both much
simpler to tackle and of supreme importance in OOP, so we did put that
in. But of course interfaces also come with their own set of problems,
mainly regarding how the BCL is structured.

What is the exact problem with multiple inheritance?

The most obvious problem is with function overriding.

Let's say have two classes A and B, both of which define a method doSomething. Now you define a third class C, which inherits from both A and B, but you don't override the doSomething method.

When the compiler seed this code...

C c = new C();
c.doSomething();

...which implementation of the method should it use? Without any further clarification, it's impossible for the compiler to resolve the ambiguity.

Besides overriding, the other big problem with multiple inheritance is the layout of the physical objects in memory.

Languages like C++ and Java and C# create a fixed address-based layout for each type of object. Something like this:

class A:
at offset 0 ... "abc" ... 4 byte int field
at offset 4 ... "xyz" ... 8 byte double field
at offset 12 ... "speak" ... 4 byte function pointer

class B:
at offset 0 ... "foo" ... 2 byte short field
at offset 2 ... 2 bytes of alignment padding
at offset 4 ... "bar" ... 4 byte array pointer
at offset 8 ... "baz" ... 4 byte function pointer

When the compiler generates machine code (or bytecode), it uses those numeric offsets to access each method or field.

Multiple inheritance makes it very tricky.

If class C inherits from both A and B, the compiler has to decide whether to layout the data in AB order or in BA order.

But now imagine that you're calling methods on a B object. Is it really just a B? Or is it actually a C object being called polymorphically, through its B interface? Depending on the actual identity of the object, the physical layout will be different, and its impossible to know the offset of the function to invoke at the call-site.

The way to handle this kind of system is to ditch the fixed-layout approach, allowing each object to be queried for its layout before attempting to invoke the functions or access its fields.

So...long story short...it's a pain in the neck for compiler authors to support multiple inheritance. So when someone like Guido van Rossum designs python, or when Anders Hejlsberg designs c#, they know that supporting multiple inheritance is going to make the compiler implementations significantly more complex, and presumably they don't think the benefit is worth the cost.

Multiple Inheritance in C#

Since multiple inheritance is bad (it makes the source more complicated) C# does not provide such a pattern directly. But sometimes it would be helpful to have this ability.

C# and the .net CLR have not implemented MI because they have not concluded how it would inter-operate between C#, VB.net and the other languages yet, not because "it would make source more complex"

MI is a useful concept, the un-answered questions are ones like:- "What do you do when you have multiple common base classes in the different superclasses?

Perl is the only language I've ever worked with where MI works and works well. .Net may well introduce it one day but not yet, the CLR does already support MI but as I've said, there are no language constructs for it beyond that yet.

Until then you are stuck with Proxy objects and multiple Interfaces instead :(

Why is multiple inheritance not supported in most of programming language?

Multiple inheritance is useful in many situations as a developer, but it greatly increases the complexity of the language, which makes life harder for both the compiler developers and the programmers.

  • One problem occurs when two parent classes have data members or methods of the same name. It is difficult to resolve which is being referenced by the sub-class.

  • Another occurs when two parent classes inherit from the same base class, forming a "diamond" pattern in the inheritance hierarchy.

  • The order that the initialisation/elaboration of the parent classes needs to be specified - this can sometimes lead to behaviour changing when the order of the inheritance changes - something may catch developers by surprise.

  • Some languages support a reference to 'super', or equivalent, which refers to an attribute of the base class for this object. That becomes difficult to support in a language with multiple inheritance.

  • Some languages attempt to provide an automatic Object-Relational Model, so the objects can be made persistent with a regular RDMS. This mapping is difficult at the best of times (it has been described as the "Vietnam War" of software development), but it is much more difficult if multiple inheritance is supported.

Why this code does NOT represent multiple inheritance in C#?

No; Multi-class inheritance (multiple inheritance) is not supported in C#.

Yes; Every type in .NET derives from Object (directly or indirectly).

The way you are understanding this is incorrect; this is NOT multi-class inheritance. This is multi-level inheritance.

Take the following example:

class A : Object

class B : A //This is what happens = Correct = Multi-level inheritance

class B : A, Object//This is what you are thinking = Incorrect = Multi-class inheritance.

Yes, class A derives from Object.

Yes, class B derives from A; but class B does NOT directly derive from Object.

As class A is derived from Object, all exposed members of Object are accessible to A. As class B is derived from A, all exposed members of A are accessible to B. That is why, all exposed members of Object are also accessible to class B.

This way, class B is also derived from Object indirectly. This is multi-level inheritance.

That is why your following statement is correct:

Class B also derives from object. Every type in .NET does.

Just a slight correction:

All types in .NET are directly derived from Object if they are not derived from another type. If they are derived from another type, then they are indirectly derived from Object. Yes, in any case, each type is derived from Object.



Related Topics



Leave a reply



Submit