|
||||
25.1 HOW NOT TO USE INHERITANCETo arrive at a methodological principle, it is often useful --- as illustrated by so many other discussions in this book --- to study first how not to do things. Understanding a bad idea helps find good ones, which we might otherwise miss. In too constantly warm a climate, a pear tree will not flower; it needs the jolt of Winter frost to attain full bloom in the Spring. Here the jolt is obligingly provided by a justly successful undergaduate textbook, used throughout the world to teach software engineering to probably more computing science students than any other book. Already in its fourth edition, it introduced some elements of object orientation, including a discussion of multiple inheritance. Here is the beginning:
The bibliographic reference is to the first edition of the present book. Apart from the unfortunate use of "objects" for classes, this is an auspicious start. The extract continues:
(classes, good!)
(no luck). Then comes the example of multiple inheritance:
(will our worst fears come true?)
(They have.) We are invited to consider that every CAR-OWNER object may be viewed as not only a person but also a car. To anyone who has studied inheritance even at an elementary level, this will be a surprise. As you will undoubtedly have figured out, the relation to use in the second case was client, not inheritance: a car-owner is a person, but has a car. In pictures:
In formal words: class CAR_OWNER inherit PERSON feature my_car: CAR; ... end -- class CAR_OWNER In the cited text, both links use the inheritance relation. The most interesting twist actually comes a little later in the discussion, when the author advises his reader to treat inheritance with caution:
Bulky indeed; just think of the poor car owner, loaded with his roof, engine and carburetor, not to mention four wheels plus a spare. This view might have been influenced by one of the picturesque phrases of Australian slang, about a car-owner who does look like he also is his car:
Inheritance is a non-trivial concept, so we can forgive the author of this extract on the grounds that he was perhaps a little far from his home turf. But the example has an important practical benefit apart from helping the reader feel smart: it reminds us of an absolute rule regarding inheritance.
-------------------------------------------------------------------- "Is-a" rule of inheritance Do not make a class B inherit from a class A unless you can somehow make the argument that one can view every instance of B also as an instance of A. -------------------------------------------------------------------- In other words, we must be able to convince someone --- if only ourselves to start with --- that "every B is an A" (hence the name: "is-a"). In spite of what you may think at first, this is a loose rule, not a strict one. Here is why:
These observations define both the usefulness and the limitations of the is-a rule. It is useful as a negative rule in the Popperian style, enabling you to detect and reject inappropriate uses of inheritance. But as a positive rule it is not sufficient; not all suggested uses that pass the rule's test will be appropriate. Gratifying as the CAR_OWNER
counter-example may be, then, any feeling of elation that we may have
gained from it will be short-lived. It was both the beginning and the end of
the unmitigated good news --- the news that some proposed uses of inheritance
are obviously wrong and easy to spot. The rest of this chapter has to contend
with the bad or at least mixed news: that in just about all other cases the
decision is a true design issue, that is to say hard, although we will
fortunately be able to find some general guidelines.
PREVIOUS SECTION ---- NEXT SECTION
|