This site contains older material on Eiffel. For the main Eiffel page, see http://www.eiffel.com.

25.1 HOW NOT TO USE INHERITANCE

To 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:

Multiple inheritance allows several objects to act as base objects and is supported in object-oriented languages such as [the notation of the present book] [M 1988].

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:

The characteristics of several different object classes

(classes, good!)

can be combined to make up a new object.

(no luck). Then comes the example of multiple inheritance:

For example, say we have an object class CAR which encapsulates information about cars and an object class PERSON which encapsulates information about people. We could use both of these to define

(will our worst fears come true?)

a new object class CAR-OWNER which combines the attributes of CAR and PERSON.

(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:

Adaptation through inheritance tends to lead to extra functionality being inherited, which can make components inefficient and bulky.

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:

  • Note the phrase ``can somehow make the argument". This is voluntarily vague: we do not require a proof that every B is an A. Many cases will leave room for discussion. Is it true that "Every savings account is a checking account"? There is no absolute answer; depending on the bank's policies and your analysis of the properties of the various kinds of account, you may decide to make class SAVINGS_ACCOUNT an heir to BANK_ACCOUNT, or put it elsewhere in the inheritance structure. Reasonable people may disagree on the decision. But the "is-a" argument must be sustainable. Once again our counter-example helps: the argument that a CAR_OWNER "is-a" CAR is not sustainable.

  • Our view of what "is-a" means will be particularly liberal. It will not, for example, disallow implementation inheritance --- a form of inheritance that many people view with suspicion --- as long as the "is-a" argument can reasonably be made.

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