54

I have come across numerous arguments against the inclusion of multiple inheritance in C#, some of which include (philosophical arguments aside):

  • Multiple inheritance is too complicated and often ambiguous
  • It is unnecessary because interfaces provide something similar
  • Composition is a good substitute where interfaces are inappropriate

I come from a C++ background and miss the power and elegance of multiple inheritance. Although it is not suited to all software designs there are situations where it is difficult to deny it's utility over interfaces, composition and similar OO techniques.

Is the exclusion of multiple inheritance saying that developers are not smart enough to use them wisely and are incapable of addressing the complexities when they arise?

I personally would welcome the introduction of multiple inheritance into C# (perhaps C##).


Addendum: I would be interested to know from the responses who comes from a single (or procedural background) versus a multiple inheritance background. I have often found that developers who have no experience with multiple inheritance will often default to the multiple-inheritance-is-unnecessary argument simply because they do not have any experience with the paradigm.

ctrl-alt-delor
  • 7,506
  • 5
  • 40
  • 52
Richard Dorman
  • 23,170
  • 16
  • 45
  • 49

34 Answers34

114

I've never missed it once, not ever. Yes, it [MI] gets complicated, and yes, interfaces do a similar job in many ways - but that isn't the biggest point: in the general sense, it simply isn't needed most of the time. Even single inheritance is overused in many cases.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I'm fresh outta votes, so consider this a +1 – Rob Oct 10 '08 at 14:51
  • Well, you can always come back in a few hours ;-p – Marc Gravell Oct 10 '08 at 14:52
  • I've heard similar arguments from developers who come from a procedural programming background. Their argument would be "objects, never had a need for them". Thats missing the point. If they're more expressive they have value (in the right situation). – Richard Dorman Oct 10 '08 at 14:58
  • 20
    Strictly speaking (and I am just paraphrasing Stroustrup here), that is true, and also it is true that single inheritance is not really needed. Furthermore, classes are not really needed either, right? It is not about "needed" but rather "nice to have" – Nemanja Trifunovic Oct 10 '08 at 14:58
  • 7
    There are situations where any single feature would help. Does that mean a language should be a kitchen sink with every possible feature you can think of? I don't believe the added complexity burden of multiple inheritance is worth it. – Jon Skeet Oct 10 '08 at 15:00
  • 25
    If you took objects away, I would miss them sorely; that is the distinction. Objects add massive value at minimal complexity. Multiple inheritance adds (arguably) minimal value at massive complexity. – Marc Gravell Oct 10 '08 at 15:00
  • But objects are actually a huge complexity over not having objects. As is the existence of inheritance, interfaces, or any other advanced concept. – Kibbee Oct 10 '08 at 15:06
  • 4
    OK, let me re-phrase; from my blinkered viewpoint as a .NET developer, /working with objects/ is simple. I know I would fail with MI very quickly. But yes, point taken - object increase complexity. It is about complexity vs reward; objects have big benefits; MI has some benefit, but not enough IMO. – Marc Gravell Oct 10 '08 at 15:09
  • Objects are a huge complexity with a commensurate payoff. Single-rooted inheritance has worked for over a decade in Java, about 20 years with Obj-C ... The C# designers were trying to prevent accidental bugs, followed a conventinal design, and (IMHO) did the right thing. Composition > Inheritance! – John Rudy Oct 10 '08 at 15:11
  • 1
    Marc, have you written code using multiple inheritance? It certainly has complexity, but it's not some horrid untamable beast that it's often made out to be. – Richard Dorman Oct 10 '08 at 15:12
  • But it does have a wild side... – Marc Gravell Oct 10 '08 at 15:14
  • 4
    MI is simple, but if you can't trust yourself not to create a massive tree-like hierarchy, then I think you shouldn't be programming at all. I think the C# designer just wanted to keep life easy for himself, MI is difficult for compilers. – gbjbaanb Oct 10 '08 at 15:22
  • 2
    Personally, I'd rather find a design that didn't need me (a mere mortal) to *understand* a massive tree-like hierarchy. – Marc Gravell Oct 10 '08 at 15:31
  • 1
    @Marc: The problem with MI isn't the strange trees, the problem is the diamonds/loops. – tloach Oct 10 '08 at 15:35
  • @tloach: true - but I was using that phrase as a direct quote from gbjbaanb – Marc Gravell Oct 10 '08 at 15:36
  • then you need to re-read it. I was referring to people who create huge trees and then say 'MI is difficult'. If they used it sensibly, they wouldn't have such self-inflicted problems. Same applies to everything, including objects. – gbjbaanb Oct 17 '08 at 19:41
  • @gbjbaanb - fair enough; it could be interpreted in either way, and I chose the wrong one; I see your point, and agree entirely! Sorry for confusion... – Marc Gravell Oct 17 '08 at 20:01
  • 1
    I haven't missed "stereotypical" multiple inheritance, but I have missed it in the way it's used in the Curiously Recurring Template Pattern (http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern). – Bradley Grainger Oct 24 '08 at 05:26
  • you probably didn't missed it because your mind is fixed firmly to the way of thought of single inheritance.. i personally find a lot of uses to it. – Letterman Oct 22 '09 at 23:21
  • 1
    It isn't needed most of the time doesn't mean that in some tiny cases you don't need it. – user310291 Apr 17 '10 at 12:00
  • @Marc, it might be a bit more than a few hours, but that +1 has just landed. Better late than never, eh? =) – Rob Aug 09 '10 at 21:34
  • @Rob - lol; nearly 2 years ;p – Marc Gravell Aug 09 '10 at 22:15
  • 1
    +1 I agree that we don't need MI, since we mostly want it to improve code reuse. But I do think that we need something, maybe some better way to compose our classes. Like with traits or [roles](http://codecrafter.blogspot.com/2010/10/roles-in-c.html). – Jordão Oct 26 '10 at 19:57
37

Prefer aggregation over inheritance!

class foo : bar, baz

is often better handled with

class foo : Ibarrable, Ibazzable
{
  ... 
  public Bar TheBar{ set }
  public Baz TheBaz{ set }

  public void BarFunction()
  {
     TheBar.doSomething();
  }
  public Thing BazFunction( object param )
  {
    return TheBaz.doSomethingComplex(param);
  }
}

This way you can swap in and out different implementations of IBarrable and IBazzable to create multiple versions of the App without having to write yet another class.

Dependency injection can help with this a lot.

Even Mien
  • 44,393
  • 43
  • 115
  • 119
Chris Cudmore
  • 29,793
  • 12
  • 57
  • 94
  • I agree. What you can do with delegation and composition vastly exceeds what you can do with multiple inheritance. And is often the more sustainable solution anyway. – Wedge Oct 10 '08 at 21:39
  • 4
    You can use mixin here, instead of manually writing the composition :-) – Ron Klein May 13 '09 at 12:04
  • Absolutely. However, I was trying to illustrate a concept, which is often best done by showing a naive implementation. – Chris Cudmore May 13 '09 at 12:51
  • 3
    Replace "aggregation" with "composition" in your example. If you come from Multiple Inheritance you NEED all the classes in your composed super-class. Here are the differences between `aggregation` and `composition`: http://en.wikipedia.org/wiki/Object_composition#Aggregation – Alex Bagnolini Jan 19 '10 at 13:19
  • Yes, you can do this, but it's a pain! If the language supports MI it's cake. – Pete Alvin Oct 01 '10 at 17:07
25

One of the issues with dealing with multiple inheritance is the distinction between interface inheritance and implementation inheritance.

C# already has a clean implementation of interface inheritance (including choice of implicit or explicit implementations) by using pure interfaces.

If you look at C++, for each class you specify after the colon in the class declaration, the kind of inheritance you get is determined by the access modifier (private, protected, or public). With public inheritance, you get the full messiness of multiple inheritance—multiple interfaces are mixed with multiple implementations. With private inheritance, you just get implementation. An object of "class Foo : private Bar" can never get passed to a function that expects a Bar because it's as if the Foo class really just has a private Bar field and an automatically-implemented delegation pattern.

Pure multiple implementation inheritance (which is really just automatic delegation) doesn't present any problems and would be awesome to have in C#.

As for multiple interface inheritance from classes, there are many different possible designs for implementing the feature. Every language that has multiple inheritance has its own rules as to what happens when a method is called with the same name in multiple base classes. Some languages, like Common Lisp (particularly the CLOS object system), and Python, have a meta-object protocol where you can specify the base class precedence.

Here's one possibility:

abstract class Gun
{ 
    public void Shoot(object target) {} 
    public void Shoot() {}

    public abstract void Reload();

    public void Cock() { Console.Write("Gun cocked."); }
}

class Camera
{ 
    public void Shoot(object subject) {}

    public virtual void Reload() {}

    public virtual void Focus() {}
}

//this is great for taking pictures of targets!
class PhotoPistol : Gun, Camera
{ 
    public override void Reload() { Console.Write("Gun reloaded."); }

    public override void Camera.Reload() { Console.Write("Camera reloaded."); }

    public override void Focus() {}
}

var    pp      = new PhotoPistol();
Gun    gun     = pp;
Camera camera  = pp;

pp.Shoot();                    //Gun.Shoot()
pp.Reload();                   //writes "Gun reloaded"
camera.Reload();               //writes "Camera reloaded"
pp.Cock();                     //writes "Gun cocked."
camera.Cock();                 //error: Camera.Cock() not found
((PhotoPistol) camera).Cock(); //writes "Gun cocked."
camera.Shoot();                //error:  Camera.Shoot() not found
((PhotoPistol) camera).Shoot();//Gun.Shoot()
pp.Shoot(target);              //Gun.Shoot(target)
camera.Shoot(target);          //Camera.Shoot(target)

In this case, only the first listed class's implementation is implicitly inherited in the case of a conflict. The class for other base types must be explicitly specified to get at their implementations. To make it more idiot-proof, the compiler can disallow implicit inheritance in the case of a conflict (conflicting methods would always require a cast).

Also, you can implement multiple inheritance in C# today with implicit conversion operators:

public class PhotoPistol : Gun /* ,Camera */
{
    PhotoPistolCamera camera;

    public PhotoPistol() {
        camera = new PhotoPistolCamera();
    }

    public void Focus() { camera.Focus(); }

    class PhotoPistolCamera : Camera 
    { 
        public override Focus() { }
    }

    public static Camera implicit operator(PhotoPistol p) 
    { 
        return p.camera; 
    }
}

It's not perfect, though, as it's not supported by the is and as operators, and System.Type.IsSubClassOf().

Hannele
  • 9,301
  • 6
  • 48
  • 68
Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
  • 2
    +++ on this one for me. Eiffel and Sather are good examples of multiple inheritance done right.www.icsi.berkeley.edu/~sather/ – mancaus Oct 10 '08 at 17:56
  • In Sather a class exposes no interface other than that defined by the interfaces it "inherits". Implementation inheritance is via an "include" keyword that does just that, but allows renaming to avoid namespace conflicts. Sather also had many other features only recently introduced into C#. – mancaus Oct 10 '08 at 17:57
  • Great response. The use of implicit operators is an interesting approach but unfortunately doesn't come with the benefits of the compiler understanding an MI tree. The correctness of any inheritance tree needs to be maintained by the developer. – Richard Dorman Oct 13 '08 at 07:45
  • 2
    A good use of multiple inheritance in C++ was as a way to implement mixins (http://en.wikipedia.org/wiki/Mixin). I think that native C# support for mixins (or private implementation inheritance) would be a helpful feature. – Bradley Grainger Oct 24 '08 at 05:32
  • +1. To the other comments about mixins: Thats why Objective-C has Categories (effictively mixins) and doesnt need MI for that reason. – Johannes Rudolph Nov 24 '09 at 14:15
15

Here is a very useful case for multiple inheritance that I run into all of the time.

As a toolkit vendor, I cannot change published API's or I will break backwards compatibility. One thing that results from that is that I cannot ever add to an interface once I have released it because it would break compilation for anyone implementing it -- the only option is to extend the interface.

This is fine for existing customers, but new ones would see this hierarchy as needlessly complex, and if I were designing it from the beginning, I would not opt to implement it this way -- I have to, or else I will lose backwards compatibility. If the interface is internal, then I just add to it and fix the implementors.

In many cases, the new method to the interface has an obvious and small default implementation, but I cannot provide it.

I would prefer to use abstract classes and then when I have to add a method, add a virtual one with a default implementation, and sometimes we do this.

The issue, of course, is if this class would likely be mixed in to something that is already extending something -- then we have no choice but to use an interface and deal with extension interfaces.

If we think we have this problem in a big way, we opt for a rich event model instead -- which I think is probably the right answer in C#, but not every problem is solved this way -- sometimes you want a simple public interface, and a richer one for extenders.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
12

C# supports single inheritance, interfaces and extension methods. Between them, they provide just about everything that multiple inheritance provides, without the headaches that multiple inheritance brings.

David Arno
  • 42,717
  • 16
  • 86
  • 131
  • (except maybe state from multiple ancestors... but I'm with you on this one ;-p) – Marc Gravell Oct 10 '08 at 14:56
  • @Marc, damn, I knew my sweeping generalisation would come back to bite me. Edited slightly to cover your point :) – David Arno Oct 10 '08 at 14:59
  • 2
    Similar, but not the same. I would also argue that extension methods come with they're own flavour of complexity. I think CodingHorror had a post on this. – Richard Dorman Oct 10 '08 at 15:01
  • 1
    Said [Coding Horror post](http://blog.codinghorror.com/monkeypatching-for-humans/), for anyone interested. – Hannele May 21 '14 at 15:22
8

Multiple inheritance isn't supported by the CLR in any way I'm aware of, so I doubt it could be supported in an efficient way as it is in C++ (or Eiffel, which may do it better given that the language is specifically designed for MI).

A nice alternative to Multiple Inheritance is called Traits. It allows you to mix together various units of behavior into a single class. A compiler can support traits as a compile-time extension to the single-inheritance type system. You simply declare that class X includes traits A, B, and C, and the compiler puts the traits you ask for together to form the implementation of X.

For example, suppose you are trying to implement IList(of T). If you look at different implementations of IList(of T), they often share some of the exact same code. That's were traits come in. You just declare a trait with the common code in it and you can use that common code in any implementation of IList(of T) -- even if the implementation already has some other base class. Here's what the syntax might look like:

/// This trait declares default methods of IList<T>
public trait DefaultListMethods<T> : IList<T>
{
    // Methods without bodies must be implemented by another 
    // trait or by the class
    public void Insert(int index, T item);
    public void RemoveAt(int index);
    public T this[int index] { get; set; }
    public int Count { get; }

    public int IndexOf(T item)
    {
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        for (int i = 0; i < Count; i++)
            if (comparer.Equals(this[i], item))
                return i;
        return -1;
    }
    public void Add(T item)
    {
        Insert(Count, item);
    }
    public void Clear()
    {   // Note: the class would be allowed to override the trait 
        // with a better implementation, or select an 
        // implementation from a different trait.
        for (int i = Count - 1; i >= 0; i--)
            RemoveAt(i);
    }
    public bool Contains(T item)
    {
        return IndexOf(item) != -1;
    }
    public void CopyTo(T[] array, int arrayIndex)
    {
        foreach (T item in this)
            array[arrayIndex++] = item;
    }
    public bool IsReadOnly
    {
        get { return false; }
    }
    public bool Remove(T item)
    {
        int i = IndexOf(item);
        if (i == -1)
            return false;
        RemoveAt(i);
        return true;
    }
    System.Collections.IEnumerator 
        System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < Count; i++)
            yield return this[i];
    }
}

And you use the trait like this:

class MyList<T> : MyBaseClass, DefaultListMethods<T>
{
    public void Insert(int index, T item) { ... }
    public void RemoveAt(int index)       { ... }
    public T this[int index] {
        get { ... }
        set { ... }
    }
    public int Count {
        get { ... }
    }
}

Of course, I'm just scratching the surface here. For a more complete description, see the paper Traits: Composable Units of Behavior (PDF).

The Rust language (from Mozilla) has implemented Traits in an interesting way: they noticed that traits are similar to default interface implementations, so they unified interfaces and traits into a single feature (which they call traits). The main difference between traits and default interface implementations (which Java now has) is that traits can contain private or protected methods, unlike traditional interface methods that must be public. If traits and interfaces are not unified into a single feature, then another difference is that you can have a reference to an interface, but you can't have a reference to a trait; a trait is not itself a type.

Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • Interesting suggestion. How is this different to using a helper class or aggregation? – Richard Dorman Oct 13 '08 at 07:54
  • How could you implement IList with aggregation or helper class (assuming you already have a base class that doesn't implement IList)? Without traits you'd still have the burden of implementing every method of IList. Besides, there are other benefits of traits--you'd have to read the paper. – Qwertie Nov 10 '09 at 00:53
  • 1
    I also think that traits would be a great addition to C#, and that it would completely supercede the need for multiple inheritance. There's already research to add traits to C#: http://scg.unibe.ch/archive/projects/Reic05a.pdf Let's just hope that one day it comes to fruition. – Jordão Apr 26 '10 at 15:19
7

I actually miss multiple inheritance for one specific reason... the dispose pattern.

EVERY time that I need to implement the dispose pattern, I say to myself: "I wish I could just derive from a class that implements the dispose pattern with a few virtual overrides." I copy and paste the same boiler-plate code into every class that implements IDispose and I hate it.

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
5

I would argue against multiple inheritance simply for the reason you state. Developers will misuse it. I've seen enough problems with every class inheriting from a utility class, just so you can call a function from every class without needing to type so much, to know that multiple inheritance would lead to bad code in many situations. The same thing could be said about GoTo, which is one of the reasons it's use is so frowned upon. I think that multiple inheritance does have some good uses, just like GoTo, In an ideal world, where they were both only used when appropriately, there would be no problems. However, the world is not ideal, so we must protect bad programmers from themselves.

Kibbee
  • 65,369
  • 27
  • 142
  • 182
  • Microsoft made similar assumptions when they introduced VB. They assumed that developers were not smart enough to design good code so the language was dumbed down accordingly. I personally found this offensive and steered away from VB and towards more expressive languages. – Richard Dorman Oct 10 '08 at 15:04
  • However, VB.Net has now extended to the point where it is basically has every feature of C#. – Kibbee Oct 10 '08 at 15:12
  • 3
    Crippling a langauge to keep developers safe isn't really a good design principle. That's a problem that Java has (nothing but classes and interfaces so it's easy to understand...). – Mark Cidade Oct 10 '08 at 22:03
  • 3
    Read Stroustrup's book on Design and Evolution. He has an uncompromising stand on this: nothing will be kept out of the language just because it will be misused. He was aiming for the competent programmer (and, frankly, I don't want incompetents writing programs anyway). – David Thornley Oct 28 '09 at 14:22
  • Nobody wants 'incompetents writing programs'... Unfortunately in the real world a lot of 'incompetents' do, and when they quit or get fired and your get stuck with their masterpieces I'm sure you'll be glad these 'incompetents' at least didn't have MI to mess around with... – Dean Kuga Jun 03 '10 at 22:44
5

YES! YES! and YES!

Seriously, I've been developing GUI libraries my entire career, and MI (Multiple Inheritance) makes this FAR easier than SI (Single Inheritance)

First I did SmartWin++ in C++ (MI heavily used) then I did Gaia Ajax and finally now Ra-Ajax and I can with extreme confident state that MI rules for some places. One of those places being GUI libraries...

And the arguments claiming that MI "is too complex" and such are mostly put there by people trying to construct language wars and happens to belong to the camp which "currently doesn't have MI"...

Just like functional programming languages (like Lisp) have been taught (by the "non-Lispers") as "too complex" by non-functional programming language advocates...

People are afraid of the unknown...

MI RULES!

Thomas Hansen
  • 5,523
  • 1
  • 23
  • 28
  • Having multiple inheritance would require that the system disallow run-time loading or creation of classes that derive from one's classes but which weren't available at build time, have upcasts and downcasts change an object's identity, or sometimes have an instances of a class derived from one which overrides and seals a virtual method use a different override for that method. None of those sound very appetizing. For what purpose is interface inheritance insufficient? – supercat Sep 27 '13 at 16:52
3

I'm happy that C# does not have Multiple Inheritance, even though it would sometimes be convenient. What I would like to see instead is the ability to provide a default implementation of an interface method. That is:

interface I
{
    void F();
    void G();
}


class DefaultI : I
{
    void F() { ... }
    void G() { ... }
}

class C : I = DefaultI
{
    public void F() { ... } // implements I.F
}

In this case, ((I)new C()).F() will call C's implementation of I.F(), while ((I)new C()).G() will call DefaultI's implementation of I.G().

There are a number of issues that the language designers would have to work out before this could be added to the language, but none that are very hard, and the result would cover many of the needs that make Multiple Inheritance desirable.

Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
  • 1
    How is that not the same thing as multiple inheritance? – xian Oct 09 '09 at 22:52
  • @kitchen: It is multiple inheritance, but only of interfaces, which is already allowed in C#. It doesn't bump in to any of the MI issues that come from inheriting *implementation*. – Jay Bazuzi Oct 10 '09 at 04:52
  • 1
    It does, though, if you're allowing them to provide a default interface (a default implementation) i.e: "class Foo : IBar = Bar, IBaz = Baz { ... }" – xian Oct 10 '09 at 23:44
  • 1
    @Jay: I agree with kitchen: what you are asking for is multiple inheritance. It is inheritance of interface, inheritance of behavior, and represents an IS-A relationship. Inheritance in C++ is precisely that. I am interested in understanding what you think MI actually is, if not this. – David Thornley Oct 28 '09 at 14:27
  • C IS-A I, but AINT-NO DefaultI. You can inherit from multiple interfaces in C# already, but only from one base class, and I'm not proposing a change to that rule. – Jay Bazuzi Oct 30 '09 at 04:19
2

I have been working with C# since it was first available as an alpha/beta release and have never missed multiple inheritance. MI is nice for some things but there are almost always other ways to achieve the same result (some of which actually end up being simpler or creating an easier to understand implementation).

Scott Dorman
  • 42,236
  • 12
  • 79
  • 110
  • 3
    Not sure I agree. There are situations where MI produces far more elegant solutions than is possible with any of the alterantive techniques discussed in this thread. It does need to be used in right situation and can be abused, but then again so can any of tools in C#s toolbox (extension methods?) – Richard Dorman Oct 13 '08 at 07:37
2

Multiple inheritance in general can be useful and many OO languages implement it one way or another (C++, Eiffel, CLOS, Python...). Is it essential? No. Is it nice to have? Yes.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88
2

Update
I challenge everyone who votes me down to show me any example of multiple inheritance that I can't easily port to a language with single inheritance. Unless anyone can show any such sample, I claim it does not exist. I have ported tons of C++ code (MH) to Java (no-MH) and that was never a problem, no matter how much MH the C++ code used.


Nobody could ever prove so far that multiple inheritance has any advantage over other techniques you mentioned in your post (using interfaces and delegates I can get exactly the same result without much code or overhead), while it has a couple of well known disadvantages (diamond problem being the most annoying ones).

Actually multiple inheritance is usually abused. If you use OO design to somehow model the real world into classes, you will never get to the point where multiple inheritance makes actually sense. Can you provide a useful example for multiple inheritance? Most of the examples I've seen so far are actually "wrong". They make something a subclass, that is in fact just an extra property and thus actually an interface.

Take a look at Sather. It is a programming language, where interfaces do have multiple inheritance, as why not (it can't create a diamond problem), however classes that are no interfaces have no inheritance whatsoever. They can only implement interfaces and they can "include" other objects, which makes these other objects a fixed part of them, but that is not the same as inheritance, it's rather a form of delegation (method calls "inherited" by including objects are in fact just forwarded to instances of these objects encapsulated in your object). I think this concept is pretty interesting and it shows you can have a complete clean OO language without any implementation inheritance at all.

Mecki
  • 125,244
  • 33
  • 244
  • 253
  • I agree that is has its complexities (diamond problem being one of them) but it is not possible to fully express multiple inheritance with interfaces, composition or extensions methods (or some combination there of). – Richard Dorman Oct 10 '08 at 15:18
  • It may only need you sometimes have to write a little bit more code, but the functionality is absolutely equal. I've ported tons of C++ apps to Java, C++ has MH, Java not, it never was a problem to port any of these, I have the same classes and same interfaces (and just some extra classes) – Mecki Oct 10 '08 at 15:24
  • It's not a question of getting it to work, it's a question of getting the code you want. I gave an example where MI would help me (wanting to add methods to released interfaces that can't change -- easy to do with abstract classes, but only if MI is available). – Lou Franco Oct 10 '08 at 15:59
  • @Lou: You don't need MI for that. Okay, I think Java can't do that, but Objective-C can do that (we regularly extend Apple's own classes with own methods) and Objective-C has no MI. – Mecki Oct 21 '08 at 17:42
2

No.

(for voting)

CrashCodes
  • 3,237
  • 12
  • 38
  • 42
2

one of the truly nice and (at the time) novel things about the DataFlex 4GL v3+ (I know, I know, Data what?) was its support for mixin inheritance - the methods from any other classes could be reused in your class; as long as your class provided the properties that these methods used, it worked just fine, and there was no "diamond problem" or other multiple-inheritance "gotchas" to worry about.

i would like to see something like this in C# as it would simplify certain kinds of abstraction and contruction issues

Steven A. Lowe
  • 60,273
  • 18
  • 132
  • 202
2

Instead of multiple inheritance, you can use mixins which is a better solution.

Community
  • 1
  • 1
Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
1

I think it would over-complicate things without providing enough ROI. We already see people butcher .NET code with too-deep inheritance trees. I can just imagine the atrocities if people had the power to do multiple inheritance.

I won't deny that it has potential, but I just don't see enough benefit.

Bob King
  • 25,372
  • 6
  • 54
  • 66
1

While there are certainly instances where it can be useful, I have found that most of the time when I think I need it, I really don't.

coder1
  • 3,447
  • 5
  • 30
  • 46
1

A colleague wrote this blog about how to get something like multiple inheritance in C# with Dynamic Compilation:

http://www.atalasoft.com/cs/blogs/stevehawley/archive/2008/09/29/late-binding-in-c-using-dynamic-compilation.aspx

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
1

I think its simple really. Just like any other complex programming paradigm, you can misuse it and hurt yourself. Can you misuse objects (oh yes!), but that doesn't mean OO is bad in itself.

Similarly with MI. If you do not have a large 'tree' of inherited classes, or a lot of classes that provide the same named methods, then you will be perfectly fine with MI. In fact, as MI provides the implementation, you'll often be better off than a SI implementation where you have to re-code, or cut&paste methods to delegated objects. Less code is better in these cases.. you can make an almighty mess of sharing code by trying to re-use objects through interface inheritance. And such workarounds don't smell right.

I think the single-inheritance model of .NET is flawed: they should have gone with interfaces only, or MI only. Having "half and half" (ie single implementation inheritance plus multiple interface inheritance) is more confusing than it should be, and not elegant at all.

I come from a MI background, and I'm not scared of or burnt by it.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
1

I have posted this here a couple of times but I just think it is really cool. You can learn how to fake MI here. I also think the article highlights why MI is such a pain even if that was not intended.

I neither miss it or need it, I prefer to use composition of objects to achieve my ends. That is really the point of the article as well.

Flory
  • 2,849
  • 20
  • 31
  • The article mentions precisely one problem with MI: the diamond pattern. To avoid the possibility of that, it goes into detail on fairly complicated work-arounds to implement MI. I'm not impressed with the reasoning: wouldn't it be simpler just to have MI and say "DON'T DO THE DIAMOND!"? – David Thornley Oct 28 '09 at 14:31
1

I've used multiple inheritence in C++ myself too, but you really have to know what you're doing in order to not get yourself in trouble, especially if you have two base classes which share a grandparent. Then you can get into issues with virtual inheritence, having to declare every constructor you're going to call down the chain (which makes binary reuse much harder)... it can be a mess.

More importantly, the way the CLI is currently built precludes MI from being implemented easily. I'm sure they could do it if they wanted, but I have other things I'd rather see in the CLI than multiple inheritence.

Things I'd like to see include some features of Spec#, like non-nullable reference types. I'd also like to see more object safety by being able to declare parameters as const, and the ability to declare a function const (meaning that you are guaranteeing that the internal state of an object won't be changed by the method and the compiler double checks you).

I think that between Single Inheritence, Multiple Interface Inheritence, Generics, and Extension Methods, you can do pretty much anything you need to. If anything could improve things for someone desiring MI, I think some sort of language construct which would would allow easier aggregation and composition is needed. That way you can have a shared interface, but then delegate your implementation to a private instance of the class you would normally inherit from. Right now, that takes a lot of boiler plate code to do. Having a more automated language feature for that would help significantly.

Nick
  • 5,875
  • 1
  • 27
  • 38
1

No, we came away from it. You do need it now.

Taryn
  • 242,637
  • 56
  • 362
  • 405
K Man
  • 27
  • 2
1

I prefer C++. I've used Java, C#, etc. As my programs get more sophisticated in such an OO environment, I find myself missing Multiple Inheritance. That's my subjective experience.

It can make for amazing spaghetti code...it can make for amazingly elegant code.

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
1

No unless Diamond problem is solved. and you can use composition till this is not solved.

Vinay Pandey
  • 8,589
  • 9
  • 36
  • 54
1

I believe languages like C# should give the programmer the option. Just because it maybe too complicated does not mean it will be too complicated. Programming languages should provide the developer with tools to build anything the programmer wants to.

You choose to use those API's a developer already wrote, you dont have too.

Signal9
  • 93
  • 3
1

Give C# implicits and you will not miss multiple inheritance, or any inheritance for that matter.

Apocalisp
  • 34,834
  • 8
  • 106
  • 155
1

No I do not. I use all other OO features to develop what I want. I use Interface and object encapsulation and I am never limited on what I want to do.

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
1

I try not to use inheritance. The less I can everytime.

Pokus
  • 11,383
  • 11
  • 37
  • 27
0

I almost don't miss multiple inheritance in C#.

If you are using multiple inhertance to define an actual domain model, then in my experience, you can often create an equally good design using single inheritance and some good design patterns.

Most of the places where I find multiple inheritance to be of real value are the places where it is not the domain itself, but some technology/framework constraint that requires you to use MI. Implementation of COM objects using ATL is a very good example of where you use multiple inheritance to implement all the necessary interfaces that you COM object needs, and an elegant solution to an ugly (compared to .NET) technology. Elegant from the point of view that it is a C++ framework!

I have a situation now though, where I could use multiple inheritance. I have one class that needs to derive features from some other domain object, but it also needs to be accessible for cross-AppDomain calls. This means that it MUST inherit from MarshalByRefObject. So in this particular case, I would really like to derive both from MarshalByRefObject and my specific domain object. That is not possible however, so my class has to implement the same interface as my domain object, and forward calls to an aggregated instance.

But this is, as I said, a case where the technology/framework places a constraint, and not the domain model itself.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Pete
  • 12,206
  • 8
  • 54
  • 70
0

I say no until the Diamond Problem (a big reason why multiple inheritence with classes is bad) is solved adequately and if the solution is as good as using interfaces. In a nutshell, the Diamond Problem basically has to do with potential ambiguity in data, method and events in classes due to multiple inheritence via classes.

P/S You "rarely" avoid a programming solution you badly need just because it is hard. "Difficulty" is no excuse for not having multiple inheritence. Multithreading is hard yet it is available in C#. A big for not having multiple inheritence is due to diamond problem (http://en.wikipedia.org/wiki/Diamond_problem). A smiliar reasoning apply to your comment about better alternatives (people solve and think in different ways so sometimes one solution is a bad idea) and suitable options already exist (why create LINQ when ADO.NET does the trick and is mature...due to the strength of one over the other.)

Phil
  • 2,143
  • 19
  • 44
  • I wonder what you mean by "until it is solved"? Any given framework's inheritance semantics will support some combination of axioms (one such would be "given X:Y:Z and an object x of type X, casting x to Y and then Z will yield the same result as casting directly to Z"). A framework which does not support multiple inheritance can support combinations of axioms which cannot be supported in a framework which does. The problem isn't one of developing frameworks--even from a semantic standpoint MI would require giving up things that are more useful. – supercat Sep 27 '13 at 00:03
  • @supercat By "until it is solved", I do not mean the diamond problem is solved. I mean an acceptable workaround is provided. That was poor choice of words on my part. – Phil Sep 30 '13 at 18:31
  • Fair enough, though it's worthwhile to note that for some of the axioms of C# types to hold, no type can inherit more than one other type that expects its virtual implementations of base members to be used or expects that protected base fields won't be accessed by any class that is neither an ancestors nor descendant. This all but forces a distinction between inheritable types that would have such expectations and those that wouldn't. In Java, .NET, and C#, they way one says a type won't do the problematic operations is to make it an interface. – supercat Sep 30 '13 at 18:53
  • While interfaces are slightly more restrictive than multiply-inheritable-things would need to be [e.g. there's no semantic reason why an interface couldn't define fields, and have each implementing type include a hidden method which would return the offset between the start of its field data and the "field" that implements that interface field, nor why an interface couldn't define "default" implementations for methods defined within itself (or even those defined in an ancestor, with the explicit proviso that in case of ambiguity the framework could select any suitable method arbitrarily) – supercat Sep 30 '13 at 18:58
0

It would make things easier, less code, if interfaces could have implementation. But could they be miss-used more than used properly? I think that until you see how it can be done properly, you wont miss it. I get annoyed with the arguments that multiple-inheritance is unsafe. It is not. But almost all language implementations are. But do we NEED it?, I don't know.

I would prefer return type covariance, this can be added easily (just relax the rules, on the return type on over-ridden methods), and is always safe.

example:

class shape {}

class circle : shape {}

interface part {
    shape Form();
}

interface wheel : part {
    circle Form();
}
ctrl-alt-delor
  • 7,506
  • 5
  • 40
  • 52
  • I'm not sure what problem there would be with allowing an interface (e.g. `IFoo`) to specify a static class (e.g. `IFooHelpers`) that if while compiling class `C` implementing that interface the compiler can't find an implementation for a member (e.g. `int DoSomething(string Bar)` it should auto-generate code `int IFoo.DoSomething(string Bar) {return IFooHelpers.Classes.DoSomething(C This, string Bar);}`, assuming the appropriate static class and method exist. – supercat Oct 31 '12 at 18:02
0

If we introduce Multiple Inheritance then we are again facing the old Diamond problem of C++...

However for those who think it's unavoidable we can still introduce multiple inheritance effects by means of composition (Compose multiple objects in an object and expose public methods which delegate responsibilities to composed object and return)...

So why bother to have multiple inheritance and make your code vulnerable to unavoidable exceptions...

S M Kamran
  • 4,423
  • 7
  • 25
  • 35
-2

Interfaces are multiple inheritance. As a matter of fact, I would consider Java/C# type interfaces the "proper" implementation of multiple inheritance. Forcing multiple inheritance through the use of interfaces, rather then allowing inheritance from multiple concrete or abstract classes forces the developer to use composition/delegation for code reuse. Inheritance should never be used for code reuse and the absence of C++ type multiple inheritance forces developers to come up with better designed classes.

user14128
  • 2,547
  • 4
  • 20
  • 16