How did C # lack of multiple inheritance make it necessary to use interfaces?

In the C # programming language, Krzysztof Cwalina states in the annotation:

we clearly decided not to add support for multiple inheritance [...] the lack of multiple inheritance forced us to add the concept of interfaces, which in turn are responsible for problems with the evolution of the structure, deeper inheritance hierarchies and many other problems.

Interfaces are the basic concept for OO programming languages. I do not adhere to the meaning "made us add the concept of interfaces"

Does Krzysztof know that it is necessary to make certain design decisions regarding the use of interfaces that would otherwise use multi-level inheritance? Or does he mean that interface were introduced in C # due to the lack of multiple inheritance? Can you give an example?

+46
c # oop interface multiple-inheritance
Jan 23 '13 at 14:49
source share
4 answers

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

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

Therefore, when MI is available as a function of the language, you can "implement" the interfaces by simply calling them (again, C ++):

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

Multiple inheritance in the general case raises many questions and problems that do not necessarily have one answer or even a good one for your specific definition of “good” (a scary diamond , anyone?). The implementation of several interfaces will cost most of these problems precisely because the concept of "inheriting" an interface is a very limited particular case of inheriting a full-blown class.

And it was here that “forced us to add the concept of interfaces”: you cannot do a lot of OO design if you are limited to a single inheritance, for example, there are serious problems with the inability to reuse code when reusing code, in fact one of the most common arguments for OO. You have to do something else, and the next step is to add multiple inheritance, but only for classes that satisfy the limitations of the interface.

So, I interpret Krzysztof's quote as

Multiple inheritance in the general case is a very complex problem that we could not handle satisfactorily, given the real life limitations on .NET development. However, interface inheritance is so much easier to solve and of paramount importance in OOP, so we did it but, of course, interfaces also have their own set of problems, mainly regarding how BCL is structured.

+24
Jan 23 '13 at 15:06
source share

From Chris Brumme :

There are several reasons why we do not implement Multiple Inheritance directly. (As you know, we support Multiple Inheritance of the interface).

I think that Krzysztof Cwalina does not state in the citation the concept of the interfaces themselves, but multiple inheritance of the interface as a multiple inheritance method.

There are several reasons why we have not provided sophisticated, verifiable, CLS-compliant version of multiple inheritance implementation:

  • Different languages ​​really have different expectations about how MI works. For example, how conflicts are resolved and whether databases are duplicated combined or redundant. Before we can implement MI in the CLR environment, we need to review all languages, find out the general concepts and decide how to express them in a language-neutral form. We would also have to decide whether MI belongs to CLS and what it would mean for languages ​​that don't want this concept (presumably VB.NET, for example). Of course, the business we are the total lead time, but we do not have the opportunity to do this for MI yet.

  • The number of places where MI really fits is actually quite small. In many cases, inheriting multiple interfaces may work instead. In other cases, you can use encapsulation and delegations. If we added a slightly different construct, for example mixins, would it really be more powerful?

  • Multiple implementation inheritance introduces many difficulties to the implementation. This complexity affects casting, layout, sending, field access, serialization, identity matching, verifiability, reflection, generics, and possibly many other places.

+11
Jan 23 '13 at 14:55
source share

I think you should read what Eric Lippert says about Interfaces . His hands are dirty, so I think he knows best.

Sometimes there are worse cases and worse cases. You should choose the less bad.

The following is a copy of the related message:




They should just make sure that the specified functions (in the interface) are implemented in the inheriting class.

Right. This is a big enough advantage to justify this feature. As others have said, an interface is a contractual obligation to implement certain methods, properties, and events. The compelling benefit of a statically typed language is that the compiler can verify that the contract your code relies on is actually running.

However, interfaces are a rather weak way of representing contractual obligations. If you need a stronger and more flexible way to present contractual obligations, look at the Code Contracts feature that ships with the latest version of Visual Studio.

C # is a great language, but sometimes it gives you the feeling that Microsoft first creates a problem (avoiding multiple inheritance) and then provides a solution that is rather tedious.

OK, I'm glad you like it.

All sophisticated software developments are the result of weighing conflicting functions against each other and trying to find a “sweet spot” that offers great benefits for low cost. Because of the painful experience, we learned that languages ​​that allow multiple inheritance for sharing purposes have relatively small advantages and relatively high costs. Allowing multiple inheritance only on interfaces that do not share implementation details provides many benefits of multiple inheritance without most of the cost.

+4
Jan 23 '13 at 15:03
source share

I think the Cwalina language is a little strong and does not exactly relate to history.

Remember that the interfaces were before C #, so saying that “we had to add interfaces to solve the x problem” doesn’t sound like that. I think the interfaces would be there by default - they should have been.

Also, remember that C # comes primarily from C ++. Or at least the people involved in creating the C # language would have a very strong background in C ++. Multiple inheritance was a recognized C ++ nightmare zone. Inheritance from several classes, which themselves can be obtained from the commonm base classes, the development of which will take precedence, etc. I mean, this is a very powerful feature, but, without a doubt, can lead to complex code.

I suspect that they dropped multiple inheritance from C # because they (the authors of the language) knew how confusing everything could become, and they wanted to avoid it. Keep in mind also that when C # was introduced, one of its selling points was its cleanliness (in impartiality not cleaner than Java, but much cleaner than C and C ++).

By the way, after 10 years of developing C # I only once wanted multiple inheritance. The user interface component that I wanted to inherit from both the visual style and some general behavior. It didn’t take me a long time to realize that what I was going to do would be a pretty awful design anyway.

+2
Jan 24 '13 at 12:52
source share



All Articles