Sign in to follow this  

[.net] C# Eliminated Multiple Inheritance?

This topic is 4417 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was wondering if anyone could explain to me the reason that Microsoft removed multiple inhertiance for C#, you can emulate it using interfaces but that is not exactly the same. Does anyone know why they choose to eliminate it?

Share this post


Link to post
Share on other sites
You can create multiple interfaces and then inherit a class from as many interfaces as you want. But you can only inherit from one class. This design scheme forces a downward tree of class structure.

Share this post


Link to post
Share on other sites
Multiple inheritance in C++ is one of the most contentious points of use in the language. There are many accademics who view it as somewhat of a broken pattern, though I suspect that that has more to do with how C++ chose to impliment it, rather than the thought of MI itself. Many other languages also eschew MI as well, both Java and the language D are examples.

Also, C# is not really meant to be so much of a "better C++" as it is its own entity. It looks similar on the surface for sake of familiarity, but its design goals and philosophies have little to do with those of C++.

Share this post


Link to post
Share on other sites
Counter question: can you give me an example as to when you would use multiple inheritance in a "real world" application?

With the ability to implement multiple interfaces I've never even dreamed of using multiple inheritance in the five years I've been working with it.

Share this post


Link to post
Share on other sites
There are good reasons for MI. I use MI a few times in my engine where my material system (which is in a dll) is derived from both the material system interface (IMaterialSystem) and a singleton class since it doesn't make sense to have more than one material system going. So the declaration looks like this:

class MaterialSystem : public Singleton< MaterialSystem >, public IMaterialSystem
{
...
};

Another use could be you have a class that represents some type of object and it is derived from both Renderable and ShadowCaster. So this object is to be rendered and will cast shadows but it's possible you want an object that's renderable but doesn't cast a shadow. It would not be a good idea to have ShadowCaster derive from Renderable (or the other way around, whatever) b/c doing that, while may reduce to SI, you may not want every object that's renderable to cast shadows. Or instead of ShadowCaster maybe you have MoveableObject. Or maybe you want all three!

The OGRE engine is a good example of using MI which does so reasonably.


-SirKnight

Share this post


Link to post
Share on other sites

The difference lies in these relationships:
On one hand you have the "IS-A" relationship, on the other the "HAS-A" or "CAN". These are very different relationships, and your design should reflect these differences.

A dog IS an animal, and it CAN bark

class Dog : Animal, IBarkable

An other fact is that MI can lead to ambiguous function calls, for example when you have class A derive from B and C, which both implement a virtual function Func().

Now when you call A.Func(), which one will be called?

I honestly believe that you can implement any system with SI, and it will come out cleaner.

Just my 2 cents,

Edo

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by SirKnight

Another use could be you have a class that represents some type of object and it is derived from both Renderable and ShadowCaster. So this object is to be rendered and will cast shadows but it's possible you want an object that's renderable but doesn't cast a shadow. It would not be a good idea to have ShadowCaster derive from Renderable (or the other way around, whatever) b/c doing that, while may reduce to SI, you may not want every object that's renderable to cast shadows. Or instead of ShadowCaster maybe you have MoveableObject. Or maybe you want all three!
-SirKnight



Renderable is an Interface. Classes in C# can implement multiple interfaces. So this is not really a problem. In your example your class which doesn't casts shadows doenst't derives from Shadowcaster. It just implements the Renderable Interface.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by SirKnight

Another use could be you have a class that represents some type of object and it is derived from both Renderable and ShadowCaster. So this object is to be rendered and will cast shadows but it's possible you want an object that's renderable but doesn't cast a shadow. It would not be a good idea to have ShadowCaster derive from Renderable (or the other way around, whatever) b/c doing that, while may reduce to SI, you may not want every object that's renderable to cast shadows. Or instead of ShadowCaster maybe you have MoveableObject. Or maybe you want all three!
-SirKnight



Renderable is an Interface. Classes in C# can implement multiple interfaces. So this is not really a problem. In your example your class which doesn't casts shadows doenst't derives from Shadowcaster. It just implements the Renderable Interface.

Share this post


Link to post
Share on other sites
Quote:
Original post by edotorpedo
An other fact is that MI can lead to ambiguous function calls, for example when you have class A derive from B and C, which both implement a virtual function Func().

Now when you call A.Func(), which one will be called?


If we inherit from two classes that both have an implemented virtual function update() what will happen is:
1. If we didnt overload update() the compiler will complain that the call is ambigous. So you will have to solve the ambiguity for it.
2. if we did overload the method we probably want to call both or one of the base classes update methods, so we need to prepend the method names with their class names: Class1::update, Class2::update()

That said, multiple iheritance can be very powerful and create clean designs if used properly. I'm a fan of them, but I don't use them very often. Most designs simply fit in better with multiple abstract interfaces, but I wouldnt want multiple inheritance removed from the language just because it isn't applicable for every problem. If we did that we would end up with a dumbed down language like Java (please don't flame me on this, its just my opinion).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by SirKnight
There are good reasons for MI. I use MI a few times in my engine where my material system (which is in a dll) is derived from both the material system interface (IMaterialSystem) and a singleton class since it doesn't make sense to have more than one material system going. So the declaration looks like this:

class MaterialSystem : public Singleton< MaterialSystem >, public IMaterialSystem
{
...
};


Very nice example for not needing MI ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by SirKnight
There are good reasons for MI. I use MI a few times in my engine where my material system (which is in a dll) is derived from both the material system interface (IMaterialSystem) and a singleton class since it doesn't make sense to have more than one material system going.

Well, first, that's not MI, since one of them is an interface. That's allowed, even in C#.
Second, "It doesn't make sense to have more than one" doesn't mean it has to be a singleton. Singletons are generally an OOP excuse for globals, nothing more. Sure, it can be handy, but it's not something you should use just because "I only need one instance of this class"

There are plenty of problems with multiple inheritance. I believe that it was never actually considered a real OO feature, but rather just C++'s way of compensating for not having interfaces.

Share this post


Link to post
Share on other sites

This topic is 4417 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this