Previous | Table of Contents | Next |
I have more information about Flonot necessarily because she is a florist, but because she is a shopkeeper. I know, for example, that I probably will be asked for money as part of the transaction, and that in return for payment I will be given a receipt. These actions are true of grocers, stationers, and other shopkeepers. Because the category Florist is a more specialized form of the category Shopkeeper, any knowledge I have of Shopkeepers is also true of Florists and hence of Flo.
The principle that knowledge of a more general category is also applicable to a more specific category is called inheritance. We say that the class Florist inherits attributes of the class (or category) Shopkeeper.
Classes can be organized into a hierarchical inheritance structure. A child class (or subclass) inherits attributes from a parent class higher in the tree. An abstract parent class is a class (such as Mammal) for which there are no direct instances; it is used only to create subclasses.
In programming languages, inheritance applies both to data values and to functions (that is, behavior). Both data fields and functions associated with a parent class become associated with child classes and are available for use when instances of a child class are created.
The concept of an inheritance hierarchy is the key to understanding not only how separate concepts can share common features, but also how ideas can override, or hide, their inherited attributes.
The search for a method to invoke in response to a given message begins with the class of the receiver. If no appropriate method is found, the search is conducted in the parent class of this class. The search continues up the parent class chain until either a method is found or the parent class chain is exhausted. In the former case, the method is executed; in the latter case, an error message is issued. If methods with the same name can be found higher in the class hierarchy, the method executed is said to override the inherited behavior.
Overriding occurs in everyday life as well as in the object-oriented world. We know that mammals, for example, give birth to live young. Yet the category Platypus inherits from class Mammal, and platypuses lay eggs. In our mental model of the universe, the concept of giving birth to live young is associated at the Mammal level of Figure 1.1, while the concept of laying eggs at level Platypus overrides the inherited behavior. When we search for information concerning the breeding habits of a specific animal, we search the most specific category before progressing to the more general.
FIGURE 1.1. A class hierarchy helps define characteristics of various material objects.
In a sense, it doesnt really matter whether I give my message to my florist directly, or to my secretary, as long as the resulting actions are satisfactory. Objects can be characterized by their behavior, and as long as the behavior is acceptable for certain problems, the particular characteristics of the object should be unimportant. In object-oriented languages, the inheritance hierarchy often is used not only for sharing code but also for describing characteristics.1 For example, the class Mammal can be viewed as both a convenient handle (or storage container) for holding our general information about Mammals, and, as well, a defining constraint. If I tell you, for example, that a certain animal is a Mammal, you immediately know a lot of information about it.
1It has been noted that these two goals are not always coincident, and should not necessarily be handled by the same mechanism. This brief overview does not permit me to discuss the subclass/subtype distinction, or introduce some of the techniques used to separate these concepts. Interested readers should consult my book An Introduction to Object-Oriented Programming, 2nd Ed.
In programming languages this simple idea becomes manifest in the notion that we can separate the declared type of a variable from the value that it holds at any particular time. Imagine that we have a class hierarchy that mirrors that shown in Figure 1.1. We might have a variable that is declared as Mammal. In fact, it could be holding a value that is of type Dog. Since a Dog is a Mammal (by which we mean that the category Dog inherits from the category Mammal), any behavior that we expect from the more general class should certainly be exhibited by an instance of the child class.
The term polymorphism is often used to describe this idea. Polymorphism means roughly many forms; the variable that is declared as Mammal can, during the course of execution, take on many different formsperhaps holding at one instance a cat, and another time a dog, at still another instance a human being.
This is an extremely simple idea with many powerful and subtle implications. It is the feature that permits the development of software frameworks, for example. A framework is a skeleton application that provides the structure, but no specific information, for solutions to a set of similar problems. The most common type of framework is a graphical user interface framework, or GUI. A GUI can be written so that it deals with a general class Window, for example (see Figure 1.2). A window has general characteristics, such as a rectangular shape, a height and width, the ability to be resized, moved around on the display surface, hidden, restored, made into an icon, and so on.
FIGURE 1.2. An inheritance hierarchy for windows.
All these general characteristics can be defined without reference to the particular contents of the window, in just the same way that we can discuss the characteristics of mammals without reference to a particular type of animal. The programmer using a framework then develops a new type of window by creating a subclass from the class Window (for example, GraphicsWindow). Features that are particular to the new application, such as the display of the contents of the window, are defined in this new class. Because the framework holds the window value in a polymorphic variable, the framework thinks the window is an instance of the class Window, whereas the programmer knows the actual value is an instance of the class GraphicsWindow.
Previous | Table of Contents | Next |