The
previous chapter demonstrates how to create new types by declaring
classes. The current chapter explores the relationship among objects
in the real world and how to model these relationships in your code.
This chapter focuses on specialization
which is
implemented in C# through inheritance
. This
chapter also explains how instances of more specialized classes can
be treated as if they were instances of more general classes, a
process known as polymorphism
. This chapter ends
with a consideration of
sealed
classes, which cannot be specialized,
abstract
classes, which exist only to be
specialized, and a discussion of the root of all classes, the class
Object
.
Classes and their instances (objects) do not exist in a vacuum, they exist in a network of interdependencies and relationships, just as we, as social animals, live in a world of relationships and categories.
The is-a
relationship is one of
specialization
. When we say that a Dog is-a
mammal, we mean that the dog is a specialized kind of
mammal. It has all the characteristics of any mammal (it bears live
young, nurses with milk, has hair), but it specializes these
characteristics to the familiar characteristics of canine
domesticus. A Cat is also a mammal. As such we expect it
to share certain characteristics with the dog that are generalized in
Mammal, but to differ in those characteristics that are specialized
in Cat.
The specialization and generalization relationships are both reciprocal and hierarchical. They are reciprocal because specialization is the obverse side of the coin from generalization. Thus, Dog and Cat specialize Mammal, and Mammal generalizes from Dog and Cat.
These relationships are hierarchical because they create a relationship tree, with specialized types branching off from more generalized types. As you move up the hierarchy you achieve greater generalization. You move up toward Mammal to generalize that Dogs and Cats and Horses all bear live young. As you move down the hierarchy you specialize. Thus, the Cat specializes Mammal in having claws (a characteristic) and purring (a behavior).
Similarly, when you say that ListBox
and
Button
are
windows, you
indicate that there are characteristics and behaviors of
Windows
that you expect to find in both of these
types. In other words, Window
generalizes the
shared characteristics of both ListBox
and
Button
, while each specializes its own particular
characteristics and behaviors.
It is common to note that two classes share functionality, and then to factor out these commonalities into a shared base class. This provides you with greater reuse of common code and easier-to-maintain code.
For example, suppose you started out creating a series of objects as illustrated in Figure 5-2.
After working with RadioButtons
,
CheckBoxes
, and Command
buttons
for a while, you realize that they share certain characteristics and
behaviors that are more specialized than Window
but more general than any of the three. You might factor these common
traits and behaviors into a common base class,
Button
, and rearrange your inheritance hierarchy
as shown in Figure 5-3. This is an example of how
generalization is used in object-oriented development.
This UML diagram depicts the relationship between the factored
classes and shows that both ListBox
and
Button
derive from Window
, and
that Button
is in turn specialized into
CheckBox
and Command
. Finally,
RadioButton
derives from
CheckBox
. You can thus say that
RadioButton
is a CheckBox
,
which in turn is a Button,
and that
Buttons
are Windows
.
This is not the only, or even necessarily the best, organization for these objects, but it is a reasonable starting point for understanding how these types (classes) relate to one another.
Actually, although this might reflect how some widget hierarchies are
organized, I am very skeptical of any system in which the model does
not reflect how I perceive reality, and when I find myself saying
that a RadioButton
is a
CheckBox
, I have to think long and hard about
whether that makes sense. I suppose a RadioButton
is a kind of checkbox. It is a checkbox that
supports the idiom of mutually exclusive choices. That said, it is a
bit of a stretch and might be a sign of a shaky design.
18.221.126.56