One of the design goals of frameworks like Java and .NET is to make it possible for code which is compiled to work with one version of a pre-compiled library, to work equally well with subsequent versions of that library, even if those subsequent versions add new features. While the normal paradigm in languages like C or C++ is to distribute statically-linked executables that contain all of the libraries they need, the paradigm in .NET and Java is to distribute applications as collections of components that are "linked" at run-time.
The COM model which preceded .NET attempted to use this general approach, but it didn't really have inheritance--instead, each class definition effectively defined both a class and an interface of the same name which contained all its public members. Instances were of the class type, while references were of the interface type. Declared a class as deriving from another was equivalent to declaring a class as implementing the other's interface, and required the new class to re-implement all public members of the classes from which one derived. If Y and Z derive from X, and then W derives from Y and Z, it won't matter if Y and Z implement X's members differently, because Z won't be able to use their implementations--it will have to define its own. W might encapsulate instances of Y and/or Z, and chain its implementations of X's methods through theirs, but there would be no ambiguity as to what X's methods should do--they'd do whatever Z's code explicitly directed them to do.
The difficulty in Java and .NET is that code is allowed to inherit members and have accesses to them implicitly refer to the parent members. Suppose one had classes W-Z related as above:
class X { public virtual void Foo() { Console.WriteLine("XFoo"); }
class Y : X {};
class Z : X {};
class W : Y, Z // Not actually permitted in C#
{
public static void Test()
{
var it = new W();
it.Foo();
}
}
answered 2013-04-08T15:49:38.213