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

后端 未结 4 1043
星月不相逢
星月不相逢 2020-12-23 21:17

In The C# Programming Language Krzysztof Cwalina states in an annotation:

we explicitly decided not to add support for multiple inheritance [...] th

相关标签:
4条回答
  • 2020-12-23 22:02

    I think you should read what Eric Lippert says about Interfaces . He has got his hands dirty so I think he knows better than every one else.

    Sometimes there are worse cases and worst cases. You have to choose the less bad one.

    Below is a copy of the linked post:


    They are there just to make sure that the said functions (in the interface) are implemented in the inheriting class.

    Correct. That's a sufficiently awesome benefit to justify the 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 a contract which your code relies upon is actually met.

    That said, interfaces are a fairly weak way to represent contractual obligations. If you want a stronger and more flexible way to represent contractual obligations, look into the Code Contracts feature that shipped with the last version of Visual Studio.

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

    Well I'm glad you like it.

    All complex software designs are a result of weighing conflicting features against each other, and trying to find the "sweet spot" that gives large benefits for small costs. We've learned through painful experience that languages that permit multiple inheritance for the purposes of implementation sharing have relatively small benefits and relatively large costs. Permitting multiple inheritance only on interfaces, which do not share implementation details, gives many of the benefits of multiple inheritance without most of the costs.

    0 讨论(0)
  • 2020-12-23 22:02

    I think Cwalina's language is a bit strong, and not entirely accurate regarding the history.

    Remember that interfaces were around before C#, so to say "we had to add interfaces to solve problem x" doesn't sound right to me. I think interfaces would have been there by default - they would have had to be.

    Also, remember that C# is derived largely from C++. Or, at least, the people involved in creating the C# language would have had very strong backgrounds in C++. Multiple Inheritance was an acknowledged nightmare area in C++. Inheriting from multiple classes which themselves may be derived from commonm base classes, working out which implementation would take precedence etc. I mean, it is a very powerful feature, but can undoubtedly lead to complex code.

    I suspect they dropped multiple inheritance from C# because they (the language authors) knew how tangled everything could become and they wanted to avoid that. Bear in mind also that when C# was introduced one of its selling points was its cleanliness (in fairless no cleaner than Java but a lot cleaner than C and C++).

    Incidentally, in 10+ years of C# development I have only wished for multiple inheritance once. A UI component which I wanted to inherit both a visual style and some common behaviour. It didn't take me long to realise that what I was intending to do would have been a pretty awful design in any case.

    0 讨论(0)
  • 2020-12-23 22:04

    From Chris Brumme:

    There are a number of reasons we don't implement Multiple Implementation Inheritance directly. (As you know, we support Multiple Interface Inheritance).

    I think what Krzysztof Cwalina states in the quote is not the concept of interfaces itself, but Multiple interface inheritance as a method of multiple inheritance.

    There are several reasons we haven't provided a baked-in, verifiable, CLS-compliant version of multiple implementation inheritance:

    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.

    0 讨论(0)
  • 2020-12-23 22:09

    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.

    0 讨论(0)
提交回复
热议问题