|< Free Open Study >|
5.2 Overriding Base Class Methods in Derived Classes
In many cases, the object-oriented designer uses inheritance to add a specialization relationship that is not behaviorally compatible to the superclass. This implies that the user wishes to override the definition of a base class message with his or her own algorithm. This is allowable within the framework of specialization and is called an overriding method. For specialization, the derived class cannot eliminate messages of the base class but the derived class can change the method that defines them (see Figure 5.5). Most object-oriented languages support the calling of the base class method from the overriding derived method. This is important since many times a designer has added data members to the derived class and wishes to handle their functionality at the derived class level. After handling the new data, the designer delegates up to the base class to let it handle its own data.
Inheritance is transitive in that if class B inherits from class A and class C inherits from class B, then class C inherits (via transitivity) class A (see Figure 5.6). This hierarchy demonstrates that a class can be both a derived class and a base class simultaneously. For example, class B is a base class of class C but a derived class of class A. One should think of inheritance as capturing a categorization hierarchy or taxonomy of the classes involved.
The containment relationship defines a black-box design where users of a class need not know about the implementation-dependent, internal classes. On the other hand, the inheritance relationship is a white-box design due to the inheritance of functionality. In order to know which messages can be sent to a derived class, I need to see the classes it inherits. If a white-box design is used where a black-box design would work as well, then we have needlessly opened our implementation to users of a class. Specialization cannot be effectively shown with a black-box design. Therefore, the opening of design details is allowable for this type of abstraction. For example, if I told you that I was a special type of XYZ, it would be useless until you understood what an XYZ is and what it does. Base classes are often used to convey high-level category information to readers of the design. In the winter of 1994, I taught a C++/object-oriented design course to a group in Singapore. Someone in the class asked me if I knew what a durian was. I told the attendee that I had no idea. She told me it was a tropical fruit unique to Southeast Asia. I still didn't know exactly what a durian was, but I had a good idea of some of its attributes and expected behaviors.
If base classes have knowledge of their derived classes, then it is implied that if a new derived class is added to a base class, the code of the base class will need modification. This is an undesirable dependency between the abstractions captured in the base and derived classes. We will see a much better solution to these types of dependencies when we discuss the topic of polymorphism later in this chapter.
|< Free Open Study >|