24 Using inheritance well mingall the thical detailsfndchisd part C,does not automatically mean that we have fully grasped the methodological consequences.Of all issues in object technology,none causes as much discussion as the question of when and how to use inheritance;sweeping opinions abound,for example on Internet discussion groups,but the literature is relatively poor in precise and useful advice In this chapter we will probe further into the meaning of inheritance,not for the sake of theory,but to make sure we use it best to benefit our software development projects. We will in particular try to understand how inheritance differs from the other inter-module relation in object-oriented system structures,its sister and rival,the client relation:when to use one,when to use the other,when both choices are acceptable.Once we have set the basic criteria for using inheritance-identifying along the way the typical cases in which it is wrong to use it-we will be able to devise a classification of the various legitimate uses,some widely accepted (subtype inheritance),others,such as implementation or facility inheritance,more controversial.Along the way we will try to learn a little from the experience in taxonomy,or systematics,gained from older scientific disciplines. 24.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 Extracts from "Soft- Here the jolt is obligingly provided by a widely successful undergraduate textbook, ware Engineering” used throughout the world to teach software engineering to probably more computing by lan Sommerville, Fscience students than any other.Already in its fourth edition,it introduced some elements of ison-Wesley,1993.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!)
24 Using inheritance well Learning all the technical details of inheritance and related mechanisms, as we did in part C, does not automatically mean that we have fully grasped the methodological consequences. Of all issues in object technology, none causes as much discussion as the question of when and how to use inheritance; sweeping opinions abound, for example on Internet discussion groups, but the literature is relatively poor in precise and useful advice. In this chapter we will probe further into the meaning of inheritance, not for the sake of theory, but to make sure we use it best to benefit our software development projects. We will in particular try to understand how inheritance differs from the other inter-module relation in object-oriented system structures, its sister and rival, the client relation: when to use one, when to use the other, when both choices are acceptable. Once we have set the basic criteria for using inheritance — identifying along the way the typical cases in which it is wrong to use it — we will be able to devise a classification of the various legitimate uses, some widely accepted (subtype inheritance), others, such as implementation or facility inheritance, more controversial. Along the way we will try to learn a little from the experience in taxonomy, or systematics, gained from older scientific disciplines. 24.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 widely successful undergraduate textbook, used throughout the world to teach software engineering to probably more computing science students than any other. 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!) Extracts from “Software Engineering” by Ian Sommerville, Fourth edition, Addison-Wesley, 1993
810 USING INHERITANCE PROPERLY $24.1 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 out 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: A proper model PERSON Inheritance Client CAR OWNER CAR 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;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 as if he also is his car:
810 USING INHERITANCE PROPERLY §24.1 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 out 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; 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 as if he also is his car: A proper model PERSON CAR_ OWNER CAR Inheritance Client
$24.1 HOW NOT TO USE INHERITANCE 811 “He has ahead like an Austin Mini with the doors open”. Cartoon by Geoff Hocking;from The Dictionary of Aussie Slang,The Five Mile Press, Melbourne, Australia,reprinted with permission. 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 us feel smarter:it reminds us of the basic rule on inheritance. “ls-a”rule of inheritance Do not make a class B inherit from a class 4 unless you can somehow make the argument that one can view every instance of B also as an instance of4. 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 S4IINGS ACCOUNT an heir to BANK ACCOUNT,or put it elsewhere in the inheritance structure,getting some help from the other criteria discussed in this chapter. Reasonable people might still disagree on the result.But for this to be the case 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
§24.1 HOW NOT TO USE INHERITANCE 811 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 us feel smarter: it reminds us of the basic rule on inheritance. 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, getting some help from the other criteria discussed in this chapter. Reasonable people might still disagree on the result. But for this to be the case 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. “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. “He has a head like an Austin Mini with the doors open”. Cartoon by Geoff Hocking; from The Dictionary of Aussie Slang, The Five Mile Press, Melbourne, Australia, reprinted with permission
812 USING INHERITANCE PROPERLY $24.2 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. 24.2 WOULD YOU RATHER BUY OR INHERIT? To choose between the two possible inter-module relations,client and inheritance,the basic rule is deceptively simple:client is has,inheritance isis.Why then is the choice not easy? To have and to be The reason is that whereas to have is not always to be,in many cases to be is also to have. No,this is neither some cheap attempt at existentialist philosophy nor a pitch to make you buy a house if you are currently renting;rather,simple observations on the difficulty of system modeling.We have already encountered an illustration of the first property- to have is not always to be-in the preceding example:a car owner has a car,but by no twist of reasoning or exposition can we assert that he is a car. What about the reverse situation?Take a simple statement about two object types from ordinary life,such as Every software engineer is an engineer. [A] whose truth we accept for its value as an example of the "is-a"relation (whatever our opinion may be as to the statement's accuracy).It seems hard indeed to think of a case which so clearly expresses"to be"rather than"to have".But now consider the following rephrasing of the property: In every software engineer there is an engineer [B] which can in turn be restated as Every software engineer has an "engineer"component. [C] Twisted,yes,and perhaps a trifle bizarre in its expression;but not fundamentally different from our premise [A]!So here it is:by changing our perspective slightly we can rephrase the“is”property as a"has
812 USING INHERITANCE PROPERLY §24.2 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. 24.2 WOULD YOU RATHER BUY OR INHERIT? To choose between the two possible inter-module relations, client and inheritance, the basic rule is deceptively simple: client is has, inheritance is is. Why then is the choice not easy? To have and to be The reason is that whereas to have is not always to be, in many cases to be is also to have. No, this is neither some cheap attempt at existentialist philosophy nor a pitch to make you buy a house if you are currently renting; rather, simple observations on the difficulty of system modeling. We have already encountered an illustration of the first property — to have is not always to be — in the preceding example: a car owner has a car, but by no twist of reasoning or exposition can we assert that he is a car. What about the reverse situation? Take a simple statement about two object types from ordinary life, such as Every software engineer is an engineer. [A] whose truth we accept for its value as an example of the “is-a” relation (whatever our opinion may be as to the statement’s accuracy). It seems hard indeed to think of a case which so clearly expresses “to be” rather than “to have”. But now consider the following rephrasing of the property: In every software engineer there is an engineer [B] which can in turn be restated as Every software engineer has an “engineer” component. [C] Twisted, yes, and perhaps a trifle bizarre in its expression; but not fundamentally different from our premise [A]! So here it is: by changing our perspective slightly we can rephrase the “is” property as a “has
$24.2 WOULD YOU RATHER BUY OR INHERIT? 813 “COMPOSITE If we look at the picture through the eyes of a programmer,we may summon an OBJECTS AND object diagram,in the style of those which served to discuss the dynamic model in an EXPANDED TYPES”,&7,page earlier chapter,showing a typical instance of a class and its components: )5d A“software engineer” object as aggregate (ENGINEER) (POET) (PLUMBER) (SOFTWARE ENGINEER) This shows an instance of SOFTWARE ENGINEER with various subobjects, representing the various posited aspects of a software engineer's personality and tasks Rather than subobjects(the expanded view)we might prefer to think in terms ofreferences: Another possible view (POET (SOFTWARE ENGINEER) (ENGINEER) (PLUMBER) Take both of these representations as ways to visualize the situation as seen from an implementation-oriented mindset,nothing more.Both suggest,however,that a client, or"has",interpretation-every software engineer has an engineer as one of his parts- is faithful to the original statement.The same observation can be made for any similar “is-a”relationship. So this is why the problem of choosing between client and inheritance is not trivial: when the "is"view is legitimate,one can always take the "has"view instead
§24.2 WOULD YOU RATHER BUY OR INHERIT? 813 If we look at the picture through the eyes of a programmer, we may summon an object diagram, in the style of those which served to discuss the dynamic model in an earlier chapter, showing a typical instance of a class and its components: This shows an instance of SOFTWARE_ENGINEER with various subobjects, representing the various posited aspects of a software engineer’s personality and tasks. Rather than subobjects (the expanded view) we might prefer to think in terms of references: Take both of these representations as ways to visualize the situation as seen from an implementation-oriented mindset, nothing more. Both suggest, however, that a client, or “has”, interpretation — every software engineer has an engineer as one of his parts — is faithful to the original statement. The same observation can be made for any similar “is-a” relationship. So this is why the problem of choosing between client and inheritance is not trivial: when the “is” view is legitimate, one can always take the “has” view instead. “COMPOSITE OBJECTS AND EXPANDED TYPES”, 8.7, page 254 A “software engineer” object as aggregate (SOFTWARE_ENGINEER) (ENGINEER) (POET) (PLUMBER) Another possible view (SOFTWARE_ENGINEER) (ENGINEER) (POET) (PLUMBER)