Previous Section  < Free Open Study >  Next Section

5.12 Inheritance Hierarchies Versus Attributes

An interesting problem arises due to confusion between attributes versus the need for an inheritance hierarchy. A design philosophy advocated by Weiner, Wilkerson, and Wirfs-Brock [10] includes examining the parts of speech associated with the English description of the system (a requirements specification). They state that nouns are good candidates for classes and objects, verbs are good candidates for operations on these classes and objects, and adjectives tend to signal inheritance. I like their methodology because it gives designers a starting point when they have no idea what their classes/objects, operations, or inheritance should be. I dislike their methodology because it starts designers off with a long list of candidates that must be refined. It puts them on a dangerous path toward the proliferation of classes, one of the more serious problems in the object-oriented paradigm. At this time, let us focus on the adjectives portion of their methodology. I have a requirements specification with the following sentence in it:

In our system, there exist red balls, green balls, and yellow balls.

Which of the designs in Figure 5.28 is a better model of the class Ball?

Figure 5.28. Two designs for the Ball class.


Many designers choose the first model, where there exists one class called Ball, which has color as an attribute. Unfortunately, the requirements specification describes a domain in which red balls bounce twice as high as green balls and yellow balls do not bounce at all. Also, if you eat a red ball you die, a yellow ball makes you sick, and a green ball makes you stronger. Now which design is better?

Another question that demonstrates the same problem can be extracted from the fruit hierarchy described earlier. Why is it considered reasonable to have a variety attribute in the Apple class but not in the Fruit class? There are different types of fruit, and we modeled that abstraction as an inheritance hierarchy. However, there are also different types of apples, and we implemented that abstraction as an attribute. Why is there a difference?

The deciding question is "Does the value of an attribute affect the behavior of the class?" If the answer is yes, then most of the time we want inheritance. If the answer is no, then we want to model the abstraction as an attribute that can take on different values. There are cases where differing values of attributes should not imply inheritance. We will discuss this class of problems a bit later in this chapter.

What would inform a designer that he or she is making a mistake if the error is to model an abstraction as an attribute when it should have been modeled as an inheritance hierarchy? As the designer begins to model methods of his or her class, he or she will notice that some methods are performing explicit case analysis on the values of attributes. This implies that inheritance might be necessary.

What would inform a designer that he or she is making a mistake if the error is to model an abstraction as an inheritance hierarchy when it should have been modeled as an attribute? All meaningful behavior on the derived classes will be the same, so it will migrate to the abstract base class. This implies that all of the derived classes lack meaningful behavior of their own and should be eliminated as irrelevant classes. The first case is much more common. As a design proceeds through many iterations and more information is gathered, it is often the case that attributes end up defining an inheritance hierarchy.

Beware of behaviors defined on derived classes which could be factored into a single behavior of the base class through parameterization via the value of a base class attribute. An example would be a designer who argues that the RedBall, GreenBall, and YellowBall classes need to exist because the print function for RedBall prints "Hi, I'm a red ball!"; the print function for GreenBall prints "Hi, I'm a green ball!"; and the print function for YellowBall prints "Hi, I'm a yellow ball!" The bounce function of ball mentioned earlier might fit into this category. Maybe the Ball class should have an attribute called Bounce-Factor, which would be zero, one, or two.

Heuristic 5.13

Explicit case analysis on the value of an attribute is often an error. The class should be decomposed into an inheritance hierarchy, where each value of the attribute is transformed into a derived class.

    Previous Section  < Free Open Study >  Next Section