Re: Composition vs. inheritance
rmoldskr+usenet@online.no wrote:
I've slowly come to the view that the famous "is-a" test is rather flawed.
The problem lies in that "is-a" is a question of _type_ -- an emu is a bird,
an array is a list, a BigInt is an integer, while what's inherited is
_behaviour_. An emu _is_ a bird, but it doesn't _behave_ like a bird; an
array _is_ a list, but it doesn't _behave_ like a list; a BigInt _is_ an
integer, but it doesn't _behave_ like an integer, a circle _is_ an ellipse,
but it doesn't _behave_ like an ellipse and so on and on.
In /Effective C++/, Scott Meyers wrote of the "is-a" test:
"... the instincts you've developed in other fields of study--including
mathematics--may not serve you as well as you expect."
As you clearly observe, specialization is not grounds for inheritance
(Mr. Meyers refers to the classic Rectangle/Square example). In fact, in
this very newsgroup, there was once a discussion on whether or not a
mathematical Vector should inherit from a Matrix (the decision was no,
for obvious reasons).
Nor does biology present a good model for inheritance: the
classification hierarchy from kingdom to species tend to be based on
genetic divergence as much as features such as ability to fly. Too many
special cases there.
The largest problem is probably the term "is-a;" to be and to have are
among some of the loosest verbs in terms of definition. "is-a", AFAICT,
is mostly used to differentiate between "has-a" in terms of composition.
Therefore, it works fine as a test between composition and inheritance,
but it is a poor indicator of when inheritance is justified and correct.
As you mention, inheritance is only justified when the interface is
inherited.
Actually, circles do behave like ellipses in all fashions, except that a
circle is an ellipse where the major and minor axises are fixed to the
same length (along with other facts that may imply). It falls under the
"specialization" rule, however.
In other words, just because something is a more specialised type of
something else, it's not necessarily useful to use inheritance between them.
(And, the other side of the coin, even when something is _not_ a subtype of
something, it _could_ be a good idea to inherit behaviour -- a flying
squirrel isn't a bird, but it might be useful to inherit bird's fly
behaviour.)
I wish textbooks would stop describing inheritance in terms of
biological examples. About the only thing that is good for is
illustrating where inheritance is a poor choice.
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth