I'm not a C++ guy, but I'm forced to think about this. Why is multiple inheritance possible in C++, but not in C#? (I know of the diamond problem, but that's not what I'm asking here). How does C++ resolve the ambiguity of identical method signatures inherited from multiple base classes? And why is the same design not incorporated into C#?
C++ Language Design – Handling Multiple Inheritance with Shared Common Ancestor
clanguage-designmultiple-inheritance
Related Solutions
In many cases, people use inheritance to provide a trait to a class. For example think of a Pegasus. With multiple inheritance you might be tempted to say the Pegasus extends Horse and Bird because you've classified the Bird as an animal with wings.
However, Birds have other traits that Pegasi don't. For example, birds lay eggs, Pegasi have live birth. If inheritance is your only means of passing sharing traits then there's no way to exclude the egg laying trait from the Pegasus.
Some languages have opted to make traits an explicit construct within the language. Other's gently guide you in that direction by removing MI from the language. Either way, I can't think of a single case where I thought "Man I really need MI to do this properly".
Also let's discuss what inheritance REALLY is. When you inherit from a class, you take a dependency on that class, but also you have to support the contracts that class supports, both implicit and explicit.
Take the classic example of a square inheriting from a rectangle. The rectangle exposes a length and width property and also a getPerimeter and getArea method. The square would override length and width so that when one is set the other is set to match getPerimeter and getArea would work the same (2*length+2*width for perimeter and length*width for area).
There is a single test case that breaks if you substitute this implementation of a square for a rectangle.
var rectangle = new Square();
rectangle.length= 5;
rectangle.width= 6;
Assert.AreEqual(30, rectangle.GetArea());
//Square returns 36 because setting the width clobbers the length
It's tough enough to get things right with a single inheritance chain. It gets even worse when you add another to the mix.
The pitfalls I mentioned with the Pegasus in MI and the Rectangle/Square relationships are both the results of a inexperienced design for classes. Basically avoiding multiple inheritance is a way to help beginning developers avoid shooting themselves in the foot. Like all design principles, having discipline and training based on them allows you to in time discover when it's okay to break from them. See the Dreyfus Model of Skill Acquisition, at the Expert level, your intrinsic knowledge transcends reliance on maxims/principles. You can "feel" when a rule doesn't apply.
And I do agree that I somewhat cheated with a "real world" example of why MI is frowned upon.
Let's look at a UI framework. Specifically let's look at a few widgets that might at first brush look like they are simply a combination of two others. Like a ComboBox. A ComboBox is a TextBox that has a supporting DropDownList. I.e. I can type in a value, or I can select from a pre-ordained list of values. A naive approach would be to inherit the ComboBox from TextBox and DropDownList.
But your Textbox derives its value from what the user has typed. While the DDL gets its value from what the user selects. Who takes precedent? The DDL might have been designed to verify and reject any input that wasn't in its original list of values. Do we override that logic? That means we have to expose the internal logic for inheritors to override. Or worse, add logic to the base class that is only there in order to support a subclass (violating the Dependency Inversion Principle).
Avoiding MI helps you sidestep this pitfall altogether. And might lead to you extracting common, reusable traits of your UI widgets so that they can be applied as needed. An excellent example of this is the WPF Attached Property which allows a framework element in WPF to provide a property that another framework element can use without inheriting from the parent framework element.
For example a Grid is a layout panel in WPF and it has Column and Row attached properties that specify where a child element should be placed in the grid's arrangement. Without attached properties, if I want to arrange a Button within a Grid, the Button would have to derive from Grid so it could have access to the Column and Row properties.
Developers took this concept further and used attached properties as a way of componentizing behavior (for example here is my post on making a sortable GridView using attached properties written before WPF included a DataGrid). The approach has been recognized as a XAML Design Pattern called Attached Behaviors.
Hopefully this provided a little more insight on why Multiple Inheritance is typically frowned upon.
You have created your own, unnecessary problem here.
- Everything must be runnable
- The default implementation of run requires proc
- Anybody implementing their own run can ignore proc (but all that useless code still adorns the class and any descendants).
- Your concrete, exception-throwing implementation of proc enables people to set up themselves up for runtime errors. Why do that?
OK, so you wanted to be helpful by providing a default implementation but you have bolted on implementation details which you know will not always be desired. You say you want to avoid code duplication but you have encumbered your hierarchy with code which will be obsolete as soon as somebody extends it.
I would strongly urge you to go the interface/abstract-base-class route here:
- Abstract base class runnable
- Abstract base class proccer
- Create proc-calling concrete implementation of runnable.
- Wherever possible (even in proc-caller class methods) refer to runnables and not proc-callers).
So your default run implentation can be used where desired but can be dropped without penalty. Also, this way people are forced to implement proc if they mix in proc-caller but you don't have to write that "Not implemented" version of proc - they can't compile their code if they do not implement proc. Why create that runtime trap when you can require them to fix things at compile time?
If you think there are other useful behaviours which should be available, you can avoid code duplication by providing "interfaces" in the same way I have shown for proc. Anybody who wants that can mix it in.
Related Topic
- Scala – How Do Traits Avoid the Diamond Problem?
- C++ – Code Reuse via Multiple Inheritance or Composition
- Multiple Inheritance Alternatives – Alternatives to Multiple Inheritance for Architecture in C#
- Multiple Inheritance – Why Reduce Multiple Inheritance to the Diamond Problem?
- Interfaces in Python: Multiple Inheritance vs. Custom Solutions
Best Answer
I think (without having hard reference), that in Java they wanted to limit the expressiveness of the language to make the language easier to learn and because code using multiple inheritance is more often too complex for its own good than not. And because full multiple inheritance is a lot more complicated to implement, so it simplified the virtual machine a lot too (multiple inheritance interacts especially badly with garbage collector, because it requires keeping pointers into the middle of object (at the beginning of the base))
And when designing C# I think they looked at Java, saw that full multiple inheritance indeed wasn't missed much and elected to keep things simple as well.
It does not. There is a syntax to call base class method from specific base explicitly, but there is no way to override only one of the virtual methods and if you don't override the method in the subclass, it's not possible to call it without specifying the base class.
There is nothing to incorporate.
Since Giorgio mentioned interface extension methods in comments, I'll explain what mixins are and how they are implemented in various languages.
Interfaces in Java and C# are limited to declaring methods only. But the methods have to be implemented in each class that inherits the interface. There is however large class of interfaces, where it would be useful to provide default implementations of some methods in terms of others. Common example is comparable (in pseudo-language):
Difference from full class is that this can't contain any data members. There are several options for implementing this. Obviously multiple inheritance is one. But multiple inheritance is rather complicated to implement. But it's not really needed here. Instead, many languages implement this by splitting the mixin in an interface, which is implemented by the class and a repository of method implementations, that are either injected into the class itself or an intermediate base class is generated and they are placed there. This is implemented in Ruby and D, will be implemented in Java 8 and can be implemented manually in C++ using the curiously recurring template pattern. The above, in CRTP form, looks like:
and is used like:
This does not require anything to be declared virtual as regular base class would, so if the interface is used in templates leaves useful optimization options open. Note, that in C++ this would probably still be inherited as second parent, but in languages that don't allow multiple inheritance it's inserted into the single inheritance chain, so it's more like
The compiler implementation may or may not avoid the virtual dispatch.
A different implementation was selected in C#. In C# the implementations are static methods of completely separate class and the method call syntax is appropriately interpreted by compiler if a method of given name does not exist, but an "extension method" is defined. This has the advantage that extension methods can be added to already compiled class and the disadvantage that such methods can't be overriden e.g. to provide optimized version.