In addition to the answers already given, here's a link to an article I think is relevant.
Excerpts:
In the object-oriented framework, inheritance is usually presented as a feature that goes hand in hand with subtyping when one organizes abstract datatypes in a hierarchy of classes. However, the two are orthogonal ideas.
- Subtyping refers to compatibility of interfaces. A type
B
is a subtype of A
if every function that can be invoked on an object of type A
can also be invoked on an object of type B
.
- Inheritance refers to reuse of implementations. A type
B
inherits from another type A
if some functions for B
are written in terms of functions of A
.
However, subtyping and inheritance need not go hand in hand. Consider the data structure deque, a double-ended queue. A deque supports insertion and deletion at both ends, so it has four functions insert-front
, delete-front
, insert-rear
and delete-rear
. If we use just insert-rear
and delete-front
we get a normal queue. On the other hand, if we use just insert-front
and delete-front
, we get a stack. In other words, we can implement queues and stacks in terms of deques, so as datatypes, Stack
and Queue
inherit from Deque
. On the other hand, neither Stack
nor Queue
are subtypes of Deque
since they do not support all the functions provided by Deque
. In fact, in this case, Deque
is a subtype of both Stack
and Queue
!
I think that Java, C++, C# and their ilk have contributed to the confusion, as already noted, by the fact that they consolidate both ideas into a single class hierarchy. However, I think the example given above does justice to the ideas in a rather language-agnostic way. I'm sure others can give more examples.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…