You are on page 1of 45

9

Object-Oriented
Programming: Part I

Objectives
• To understand inheritance and software reusability.
• To understand base classes and derived classes.
• To learn how to create and use interfaces.
• To understand the member access modifiers protected
and internal.
Say not you know another entirely, till you have divided an
inheritance with him.
Johann Kasper Lavater
This method is to define as the number of a class the class of
all classes similar to the given class.
Bertrand Russell
Good as it is to inherit a library, it is better to collect one.
Augustine Birrell

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 8/7/01

460 Object-Oriented Programming: Part I Chapter 9

Outline
9.1 Introduction
9.2 Base Classes and Derived Classes
9.3 protected and internal Members
9.4 Relationship between Base Classes and Derived Classes
9.5 Constructors and Destructors in Derived Classes
9.6 Implicit Derived-Class-Object to Base-Class-Object Conversion
9.7 Software Engineering with Inheritance
9.8 Composition vs. Inheritance
9.9 Case Study: Point, Circle, Cylinder
9.10 Case Study: Creating and Using Interfaces
Summary • Terminology • Self-Review Exercises • Answers to Self-Review Exercises • Exercises

9.1 Introduction
In this chapter and the next we discuss object-oriented programming (OOP) and one of its
key component technologies—inheritance. Inheritance is a form of software reusability in
which new classes are created from existing classes by absorbing their attributes and be-
haviors and embellishing these with capabilities the new classes require. Software reusabil-
ity saves time in program development. It encourages reuse of proven and debugged high-
quality software, thus reducing problems after a system becomes operational. These are ex-
citing possibilities.
When creating a new class, instead of writing completely new instance variables and
instance methods, the programmer can designate that the new class is to inherit the instance
variables and instance methods of a previously defined base class. The new class is referred
to as a derived class. Each derived class itself becomes a candidate to be a base class for
some future derived class.
The direct base class of a derived class is the base class from which the derived class
explicitly inherits (via operator :). An indirect base class is inherited from two or more
levels up the class hierarchy.
With single inheritance, a class is derived from one base class. C# does not support
multiple inheritance (as C++ does) but it does support the notion of interfaces. Interfaces
help C# achieve many of the advantages of multiple inheritance without the associated
problems. We will discuss the details of interfaces in this chapter where we consider both
general principles as well as a detailed specific example of creating and using interfaces.
A derived class normally adds instance variables and instance methods of its own, so
a derived class is generally larger than its base class. A derived class is more specific than
its base class and represents a smaller group of objects. With single inheritance, the derived
class starts out essentially the same as the base class. The real strength of inheritance comes
from the ability to define in the derived class additions to, or replacements for, the features
inherited from the base class.

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 8/7/01

Chapter 9 Object-Oriented Programming: Part I 461

Every object of a derived class is also an object of that derived class’s base class. How-
ever, the converse is not true—base class objects are not objects of that base class’s derived
classes. We will take advantage of this “derived class-object-is-a-base class-object” rela-
tionship to perform some powerful manipulations. For example, we can link a wide variety
of different objects related to a common base class through inheritance into a linked list of
base class objects. This allows a variety of objects to be processed in a general way. As we
will see in this chapter, this is a key thrust of object-oriented programming.
We add a new form of member access control in this chapter, namely protected
access. Derived class methods and methods can access protected base class members.
Experience in building software systems indicates that significant portions of the code
deal with closely related special cases. It becomes difficult in such systems to see the “big
picture” because the designer and the programmer become preoccupied with the special
cases. Object-oriented programming provides several ways of “seeing the forest through
the trees”—a process called abstraction.
If a procedural program has many closely related special cases, then it is common to
see switch structures or nested if/else structures that distinguish among the special
cases and provide the processing logic to deal with each case individually. We will show
how to use inheritance and polymorphism to replace such switch logic with much sim-
pler logic.
We distinguish between the “is a” relationship and the “has a” relationship. “Is a” is
inheritance. In an “is a” relationship, an object of a derived class type may also be treated
as an object of its base class type. “Has a” is composition (as we discussed in Chapter 8).
In a “has a” relationship, a class object has one or more objects of other classes as members.
For example, a car has a steering wheel.
A derived class’s methods may need to access certain of its base class’s instance vari-
ables and methods.
Software Engineering Observation 9.1
A derived class cannot directly access private members of its base class. 9.1

This is a crucial aspect of software engineering in C#. If a derived class could access
the base class’s private members, this would violate information hiding in the base
class.
Common Programming Error 9.1
Hiding private members is a huge help in testing, debugging and correctly modifying sys-
tems. If a derived class could access its base class’s private members, it would then be
possible for classes derived from that derived class to access that data as well, and so on.
This would propagate access to what is supposed to be private data, and the benefits of
information hiding would be lost throughout the class hierarchy. 9.0

A derived class can, however, access the public, protected and internal
members of its base class if it is in the same project as the base class. Base class members
that should not be accessible to a derived class via inheritance are declared private in
the base class. A derived class can effect state changes in base class private members
only through public, protected and internal methods provided in the base class
and inherited into the derived class.

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 8/7/01

462 Object-Oriented Programming: Part I Chapter 9

A problem with inheritance is that a derived class can inherit methods that it does not
need or should not have. When a base class member is inappropriate for a derived class,
that member can be overridden (redefined) in the derived class with an appropriate imple-
mentation.
Perhaps most exciting is the notion that new classes can inherit from abundant class
libraries. Organizations develop their own class libraries and can take advantage of other
libraries available worldwide. Someday, most software may be constructed from standard-
ized reusable components just as hardware is often constructed today. This will help meet
the challenges of developing the ever more powerful software we will need in the future.

9.2 Base Classes and Derived Classes
Often an object of one class “is an” object of another class as well. A rectangle certainly is
a quadrilateral (as are squares, parallelograms and trapezoids). Thus, class Rectangle
can be said to inherit from class Quadrilateral. In this context, class Quadrilat-
eral is a base class and class Rectangle is a derived class. A rectangle is a specific type
of quadrilateral, but it is incorrect to claim that a quadrilateral is a rectangle (the quadrilat-
eral could be a parallelogram). Figure 9.1 shows several simple inheritance examples of
base classes and potential derived classes.

Base class Derived classes

Student GraduateStudent
UndergraduateStudent
Shape Circle
Triangle
Rectangle
Loan CarLoan
HomeImprovementLoan
MortgageLoan
Employee FacultyMember
StaffMember
Account CheckingAccount
SavingsAccount

Fig. 9.1 Some simple inheritance examples.

Because inheritance normally produces derived classes with more features than their
base classes, the terms base class and derived class can be confusing. There is another way,
however, to view these terms that makes perfectly good sense. Because every derived class
object “is an” object of its base class, and because one base class can have many derived
classes, the set of objects represented by a base class is normally larger than the set of
objects represented by any of that base class’s derived classes. For example, the base class
Vehicle represents in a generic manner all vehicles, such as cars, trucks, boats, bicycles,

© Copyright 1992–2002 by Deitel & Associates, Inc. All Rights Reserved. 8/7/01

A class exists in a hier- archical relationship with its derived classes. However. class TwoDimensionalShape could be defined in C# as follows: class TwoDimensionalShape : Shape { // definition of class TwoDimensionalShape } With inheritance. private members of a base class are not directly accessible from that class’s derived classes. And so on. Thus. Other methods of class Object are discussed as they are needed in the text. For example. To specify that class TwoDimensionalShape is derived from (or inherits from) class Shape. For example. These people consist of employees. Inc. Inheritance relationships form tree-like hierarchical structures. Student and Alumni. based on this class hierarchy that we can state.2. Also. A typical university community has thousands of people who are community members. There are abundant examples of hierarchies in the real world but students are not accustomed to categorizing the real world in this manner. but it is when a class is used with the mechanism of inheritance that the class becomes either a base class that supplies attributes and behaviors to other classes. students can be graduate students or undergraduate students.” or “a Teacher is a Faculty member. starting from the bottom of the diagram. so it takes some adjustment in their thinking. an Administrator also is an Object because all classes in C# have Object as one of their direct or indirect base classes.3. 9. or the class becomes a derived class that inherits those attributes and behaviors. All other base class members become members of the derived class using their original © Copyright 1992–2002 by Deitel & Associates. All Rights Reserved. This yields the inheritance hierarchy shown in Fig. Faculty mem- bers are either administrators (such as deans and department chairpersons) or teaching faculty. And in C#. Another substantial inheritance hierarchy is the Shape hierarchy of Fig. A class can certainly exist by itself. 9. “an Employee is a Communi- tyMember. Undergraduate students can be freshman. is an Employee and is a Communi- tyMember. Remember that although the private members are inaccessible. except for constructors and destructors. The arrows in the hierarchy represent the “is a” relationship. biology students have had some practice with hierarchies. Everything we study in biology is grouped into a hierarchy headed by living things and these can be plants or animals and so on. all classes in C# are related in a hierarchical relationship in which they share the 6 methods defined by class Object that include the ToString method discussed previously. an Administrator is a Faculty member. Note that the inheritance hierarchy could contain many other classes. juniors. you can follow the arrows and apply the is a relationship all the way up to the topmost base class in the hierarchy. derived class Car represents only a small subset of all the Vehicles in the world. stu- dents and alumni. Let us develop a simple inheritance hierarchy. and seniors. Members of the base class that are declared as internal are only acces- sible in a derived class if both the base class and its derived class are in the same project. For example.” CommunityMember is the direct base class of Employee. they are inherited. CommunityMember is an indirect base class of all the other classes in the hierarchy diagram. Actually. all members of a base class are inherited.Chapter 9 Object-Oriented Programming: Part I 463 etc. Employees are either faculty members or staff members. 8/7/01 . In fact. sophomores.

A base class’s private members are accessible only in methods of that base class. Objects of all classes derived from a common base class can all be treated as objects of that base class. 9. 8/7/01 . Shape TwoDimensionalShape ThreeDimensionalShape Circle Square Triangle Sphere Cube Tetrahedron Fig.2 It is possible to treat base class objects and derived class objects similarly..2 An inheritance hierarchy for university CommunityMembers. or within the definition of the base class. 9. Software Engineering Observation 9. Inc.3 protected and internal Members A base class’s public members are accessible anywhere the program has a reference to that base class type or one of its derived class types. public members of the base class become public members of the derived class and protected members of the base class become protected members of the derived class).e.464 Object-Oriented Programming: Part I Chapter 9 member access (i. We will consider many examples in which we can take advantage of this relationship with an ease of programming not available in non-object-oriented languages such as C. 9. that com- monality is expressed in the attributes and behaviors of the base class. CommunityMember Employee Student Alumni Faculty Staff Administrator Teacher Fig.2 Constructors and destructors are never inherited—they are specific to the class in which they are defined. A base class’s protected access members serve as an intermediate level of protec- tion between public and private access. 9. All Rights Reserved. or any classes that are derived from that class. A base class’s protected members may be accessed only in that base class. © Copyright 1992–2002 by Deitel & Associates. It can only be accessed by a derived class. The protected members cannot be accessed by making reference to it using the base class name or a name of an instance of that base class.3 A portion of a Shape class hierarchy.

All members are ints and are declared static. the base class method may be accessed from the derived class by preceding the base class method name with keyword base followed by the dot operator (. two and three. 54 and 61. two is declared internal and three is declared protected internal.). Get- NotDerivedMembers. attempts to make reference to the three variables as if they are member of class NotDerived. there can be class members that are declared as both protected and internal. Class Derived attempts to access the different members of MyClass as if they are members of Derived itself. so none of these variable exist as members of class NotDerived. Finally. We then try to access the variables as members of MyClass on lines 47. which contains only three members—one. each indented by three spaces. The next three methods are exactly the same as the last three methods of class Derived.4 define class MyClass. for the same reasons. As we mentioned earlier. protected and internal members of the base class simply by using the member names. This method output three error messages. This class does not inherit from the class where one.6 clearer. 9. For instance. Wherever we cannot access a member in this example. Unlike protected members. This indicates that the member can have the properties of a protected member or an internal member. A base class’s internal members may be accessed only in the same project (internal members have what is called project access). This way they can see the errors for themselves. This simply makes the final output shown in Fig. a protected member may not be accessed by making refer- ence to it using the base class name. This technique is illustrated several times throughout the chapter. This variable is then accessible where protected variables are accessible. we will print a message stating this.Chapter 9 Object-Oriented Programming: Part I 465 Another intermediate level of access is known as internal. like the one on line 47. Class NotDerived attempts to access all members again. All Rights Reserved. we cannot access the protected member of class MyClass. © Copyright 1992–2002 by Deitel & Associates. The next example demonstrates some of the subtleties of protected and internal members of a class. The difference between the variables is that one is declared pro- tected. Lines 12–17 of Fig. If another project makes reference to the internal members’ class. internal members can be accessed through an instance to the class where the internal member is originally defined. Note that an internal member is accessible in any part of the current project—not just in classes derived from the class where the member is defined. We are able to access all variables but one. 9. 32 and 40. and contains a class that inherits from the original class. Again. two and three are defined. 8/7/01 . Inc. but this time for a class that is not inherited from MyClass. The students should feel free to change the program so that it tries to access these members. When a derived class method overrides a base class method. variable one in the last example could have been declared as protected internal static int one = 1. All three are accessed successfully on lines 25. The first method in this class. and also where internal variables are accessible. In the same project we define two other classes—Derived (lines 19–64) and Not- Derived (lines 66–99). Derived class methods can normally refer to public. the protected variable. this member will not be accessible.

Inc. 6 7 namespace InsideProjectNamespace 8 { 9 // MyClass contains one protected member.4 Demonstrating protected and internal members inside a project.4: InsideProject. 4 5 using System. 33 } 34 35 // protected internal members are accessible 36 // if either protected members or internal 37 // members are accessible 38 public static int GetDerivedThree() 39 { 40 return Derived. © Copyright 1992–2002 by Deitel & Associates. 48 } 49 50 // internal members are accessible 51 // in all classes of the same project Fig. 8/7/01 .cs 2 // Demonstrating the accessibility of protected and internal 3 // members when they are defined in the current project.three. 16 protected internal static int three = 3. 15 internal static int two = 2. 17 } 18 19 public class Derived : MyClass 20 { 21 // protected members are accessible as 22 // members of derived classes 23 public static int GetDerivedOne() 24 { 25 return Derived. 41 } 42 43 // protected members not accessible as members of the 44 // original class outside that class it was defined in 45 public static string GetMyClassOne() 46 { 47 return "MyClass.one generates an error". All Rights Reserved.one. 466 Object-Oriented Programming: Part I Chapter 9 1 // Fig. 10 // one internal member and one 11 // protected internal member 12 public class MyClass 13 { 14 protected static int one = 1. 9.two. 26 } 27 28 // internal members are accessible as members 29 // of derived classes in the same project 30 public static int GetDerivedTwo() 31 { 32 return Derived. 9.

In Fig.three. 90 } 91 92 // the internal member is accessible. Inc. All Rights Reserved. Chapter 9 Object-Oriented Programming: Part I 467 52 public static int GetMyClassTwo() 53 { 54 return MyClass.one generates an error". as shown on lines 20 and 34.two.two. we create one more classes called Derived.4 Demonstrating protected and internal members inside a project. 9. Class Derived still inherits members one and three. 75 } 76 77 // protected members cannot be accessed as members of 78 // MyClass unless we are in the definition of MyClass 79 public static string GetMyClassOne() 80 { 81 return "MyClass. so the 93 // protected internal member is accessible as well 94 public static int GetMyClassThree() 95 { 96 return MyClass. Member two. 97 } 98 99 } // end class NotDerived 100 } // end namespace InsideProject Fig. the internal member. so 58 // protected internal members are accessible 59 public static int GetMyClassThree() 60 { 61 return MyClass. 9.two generates an error\n" + 74 " NotDerived.three generates an error". 55 } 56 57 // internal members are accessible. 82 } 83 84 // internal members are accessible throughout 85 // the project as a member of the class where 86 // the member is defined 87 public static int GetMyClassTwo() 88 { 89 return MyClass. is not acces- © Copyright 1992–2002 by Deitel & Associates.one generates an error\n" + 73 " NotDerived. 8/7/01 .5. this time in a separate project that makes reference to our last project. 62 } 63 64 } // end class Derived 65 66 public class NotDerived 67 { 68 // no members are accessible as members of NotDerived. 69 // because this class is not derived from MyClass 70 public static string GetNotDerivedMembers() 71 { 72 return " NotDerived.three.

Finally.5 Demonstrating protected and internal members outside a project.cs 2 // Demonstrating the accessibility of protected and internal 3 // members when they are defined in a different project. 21 } 22 23 // internal members not accessible outside 24 // of the project where they are defined 25 public static string GetDerivedTwo() 26 { 27 return "Derived. 8/7/01 . © Copyright 1992–2002 by Deitel & Associates. 28 } 29 30 // protected members are accessible.5: OutsideProject. 6 using InsideProjectNamespace. 9. MyClass. 1 // Fig.one will generate an error". it will 11 // not have any access to MyClass's members 12 namespace OutsideProjectNamespace 13 { 14 public class Derived : MyClass 15 { 16 // protected members are accessible 17 // in derived classes as members of the derived class 18 public static int GetDerivedOne() 19 { 20 return Derived. Inc.one nor MyClass. so 31 // protected internal members are also accessible 32 public static int GetDerivedThree() 33 { 34 return Derived. 35 } 36 37 // protected members are not accessible outside 38 // the class where they are defined 39 public static string GetMyClassOne() 40 { 41 return "MyClass.two will generate an error".three. MyClass. 4 5 using System. 468 Object-Oriented Programming: Part I Chapter 9 sible due to the fact that internal members can only be referenced within the project that they are defined in.two is also not accessible (line 48) for the same reason. because nei- ther MyClass.one. MyClass. 7 8 // we do not create a NotDerived class in this namespace -- 9 // if a class is not defined in the same project as class 10 // MyClass and is not derived from this class. 9.Two are.One is not accessible because we are not referencing the variable within the definition of MyClass itself. All Rights Reserved. 42 } 43 44 // internal members not accessible outside 45 // the project where they are defined 46 public static string GetMyClassTwo() Fig.Three is not accessible.

9. 4 5 using System. 57 } 58 59 } // end class Derived 60 61 } // end namespace OutsideProject Fig.GetDerivedOne() + 27 "\n". 49 } 50 51 // neither protected nor internal members are 52 // accessible.Derived. Inc.three will generate an error". 12 // and displays their results 13 static void Main( string[] args ) 14 { 15 string output. Fig.6. 23 24 // accessing a protected member in current class 25 output += "Derived.Forms. All Rights Reserved. © Copyright 1992–2002 by Deitel & Associates. 28 29 // accessing an internal member in current class Fig.5 Demonstrating protected and internal members outside a project. 9. 9. 9. 8/7/01 .6: ProtectedAndInternal 2 // Demonstrating the difference between protected and internal 3 // members of a class. 6 using System.two will generate an error". 16 17 // call all methods in InsideProject to 18 // demonstrate the accessibility of protected 19 // and internal members when they are defined 20 // in the current project 21 output = "InsideProjectNamespace\n" + 22 "------------------------------\n\n". calls all the methods in the last two projects and displays the results in a MessageBox.GetDerivedOne() = " + 26 InsideProjectNamespace.6 Displaying the accessibility of protected and internal members in various scenarios.Windows. The last project in this example. Chapter 9 Object-Oriented Programming: Part I 469 47 { 48 return "MyClass. 1 // Fig. so protected internal members are 53 // not accessible 54 public static string GetMyClassThree() 55 { 56 return "MyClass. 7 8 class ProtectedAndInternal 9 { 10 // this method calls all the methods 11 // created in the previous two projects.

GetNotDerivedMembers() =\n" + 77 InsideProjectNamespace.GetMyClassThree() = " + 53 InsideProjectNamespace.GetMyClassOne() = " + 42 InsideProjectNamespace. 49 50 // accessing a protected internal member 51 // in current project 52 output += "Derived. 39 40 // accessing a protected member in current project 41 output += "Derived.NotDerived.GetMyClassTwo() = " + 65 InsideProjectNamespace. 61 62 // accessing an internal member in a current 63 // project but unrelated class 64 output += "NotDerived.NotDerived. 74 75 // accessing all members of an unrelated class 76 output += "NotDerived.GetMyClassOne() = " + 59 InsideProjectNamespace.GetDerivedTwo() + 32 "\n". 67 68 // accessing a protected internal member in a 69 // current project but unrelated class 70 output += "NotDerived.GetMyClassThree() 73 + "\n\n". 470 Object-Oriented Programming: Part I Chapter 9 30 output += "Derived. 44 45 // accessing an internal member in current project 46 output += "Derived.GetMyClassTwo() + 48 "\n".GetDerivedTwo() = " + 31 InsideProjectNamespace.Derived.NotDerived.GetMyClassThree()" + 71 " = " + 72 InsideProjectNamespace.GetMyClassOne() + 43 "\n".GetMyClassOne() 60 + "\n".NotDerived.GetDerivedThree() = " + 37 InsideProjectNamespace. Inc.Derived. 33 34 // accessing a protected internal member 35 // in current class 36 output += "Derived.Derived. 79 80 // call all methods in InsideProject to 81 // demonstrate the accessibility of protected 82 // and internal members when they are defined Fig.GetDerivedThree() + 38 "\n\n". All Rights Reserved.GetMyClassTwo() 66 + "\n". 55 56 // accessing a protected member in a current 57 // project but unrelated class 58 output += "NotDerived.GetMyClassTwo() = " + 47 InsideProjectNamespace. © Copyright 1992–2002 by Deitel & Associates.GetNotDerivedMembers() 78 + "\n\n\n".Derived.6 Displaying the accessibility of protected and internal members in various scenarios.Derived. 9.GetMyClassThree() 54 + "\n\n". 8/7/01 .

Show( output.GetDerivedThree() 97 + "\n\n".GetMyClassOne() = " + 100 OutsideProjectNamespace.Derived.GetMyClassTwo() = " + 104 OutsideProjectNamespace.Derived. 110 111 MessageBox. 113 MessageBoxButtons. © Copyright 1992–2002 by Deitel & Associates.Derived. 102 103 output += "Derived. 106 107 output += "Derived. Chapter 9 Object-Oriented Programming: Part I 471 83 // in the current project 84 output += "OutsideProjectNamespace\n" + 85 "--------------------------------\n\n".GetDerivedTwo() 93 + "\n". Inc. 8/7/01 .GetMyClassTwo() 105 + "\n".OK. 86 87 output += "Derived.GetMyClassThree() 109 + "\n". 114 115 } // end method Main 116 117 } // end class ProtectedAndInternal Fig.GetDerivedThree() = " + 96 OutsideProjectNamespace. 90 91 output += "Derived.GetDerivedTwo() = " + 92 OutsideProjectNamespace.GetMyClassOne() 101 + "\n". All Rights Reserved.GetDerivedOne() 89 + "\n". 94 95 output += "Derived.6 Displaying the accessibility of protected and internal members in various scenarios. 9. MessageBoxIcon.Derived.Information ).GetMyClassThree() = " + 108 OutsideProjectNamespace.GetDerivedOne() = " + 88 OutsideProjectNamespace. 112 "Demonstrating protected and internal members".Derived. 98 99 output += "Derived.Derived.

This can only be done when the base class reference is actually referencing a derived class object. otherwise. an explicit cast can be used to convert a base class reference to a derived class reference. 472 Object-Oriented Programming: Part I Chapter 9 Fig.6 Displaying the accessibility of protected and internal members in various scenarios. Exceptions are discussed in detail in Chapter 11. But the reverse is not true: A base class object is not also automatically a derived class object. Inc. Common Programming Error 9. 9. C# will indicate an InvalidCastException—an indication that the cast operation is not allowed.2 However.3 Assigning an object of a base class to a derived class reference (without a cast) is a syntax error. 8/7/01 . All Rights Reserved. 9. despite the fact that objects of a variety of classes derived from a particular base class may be quite different from one another.2 Treating a base class object as a derived class object can cause errors. For example. 9. This makes possible some interesting manipulations.4 Relationship between Base Classes and Derived Classes An object of a derived class can be treated as an object of its base class. Common Programming Error 9.3 © Copyright 1992–2002 by Deitel & Associates. 9. we can create an array of references to them—as long as we treat them as base class objects.

cs 2 // Demonstrating and testing a Point class. this must be done in order to send that object any of its messages that do not appear in that base class.Forms. int b ) 20 { 21 // implicit call to base class constructor occurs here 22 SetPoint( a. 41 } 42 43 } // end property X 44 Fig.3 Our first example of inheritance is shown in Fig. int b ) 27 { 28 X = a. it is acceptable to cast that object back to its own type. 9. 30 } 31 32 public int X 33 { 34 get 35 { 36 return x. Inc.7 Assigning derived class references to base class references. 5 using System. 23 } 24 25 // set x and y coordinates of the Point 26 public void SetPoint( int a. We now formalize the inheritance concept. 3 4 using System. b ). 6 7 public class Point 8 { 9 protected int x.Windows. 29 Y = b.7: InheritanceTest. 0 ). 37 } 38 set 39 { 40 x = value. y. // coordinates of the point 10 11 // no argument constructor 12 public Point() 13 { 14 // implicit call to base class constructor occurs here 15 SetPoint( 0. 1 // Fig. Chapter 9 Object-Oriented Programming: Part I 473 Software Engineering Observation 9. 9. 9.3 If an object has been assigned to a reference of one of its base classes. 16 } 17 18 // constructor 19 public Point( int a. All Rights Reserved. In fact. © Copyright 1992–2002 by Deitel & Associates. 8/7/01 . 9. Every application we defined has used some of the techniques presented here.7.

62 } 63 64 } // end class Point 65 66 // definition of class Circle 67 public class Circle : Point // inherits from Point 68 { 69 protected double radius. All Rights Reserved. 50 } 51 set 52 { 53 y = value. int a. 474 Object-Oriented Programming: Part I Chapter 9 45 public int Y 46 { 47 get 48 { 49 return y. 54 } 55 56 } // end property Y 57 58 // convert the point into a string representation 59 public override string ToString() 60 { 61 return "[" + x + ". Inc. 94 } 95 96 } // end property Radius 97 98 // calculate area of Circle Fig. int b ) : base( a. 8/7/01 . 83 } 84 85 public double Radius 86 { 87 get 88 { 89 return radius. " + y + "]". © Copyright 1992–2002 by Deitel & Associates. 70 71 // no argument constructor 72 public Circle() 73 { 74 // implicit call to base class constructor here 75 Radius = 0. 90 } 91 set 92 { 93 radius = value. 76 } 77 78 // constructor that uses base to call the 79 // base class constructor 80 public Circle( double r.7 Assigning derived class references to base class references. 9. b ) 81 { 82 Radius = r.

All Rights Reserved.2:F}".ToString() + ". Inc. // assign Circle to pointRef 132 133 output += "\n\nCircle c (via pointRef): " + 134 pointRef. 143 144 output += "\nArea of c (via circleRef): " + 145 String.7 Assigning derived class references to base class references.ToString().Area() ). Chapter 9 Object-Oriented Programming: Part I 475 99 public double Area() 100 { 101 return Math. 50 ). 146 147 // attempt to refer to Point object with 148 // Circle reference 149 if ( p. 122 123 p = new Point( 30. 121 string output. 120.GetType() == typeof( Circle ) ) 150 { 151 circleRef = ( Circle ) p. 8/7/01 . 152 output += "\n\ncast successful".Format( "{0. 9. 102 } 103 104 // convert the Circle to a String 105 public override string ToString() 106 { 107 return "Center = " + base.7. 128 129 // use the "is a" relationship to refer to a Circle 130 // with a Point reference 131 pointRef = c. Fig. © Copyright 1992–2002 by Deitel & Associates. circleRef.ToString() + 127 "\nCircle c: " + c.ToString(). 120 Circle circleRef.PI * Radius * Radius.ToString(). 89 ). 135 136 // use downcasting (casting a base class reference to 137 // a derived class data type) to assign pointRef to 138 // circleRef 139 circleRef = ( Circle ) pointRef. 124 c = new Circle( 2. p. 125 126 output = "Point p: " + p. 115 class InheritanceTest 116 { 117 static void Main( string[] args ) 118 { 119 Point pointRef. Radius = " + 108 radius. 109 } 110 111 } // end class Circle 112 113 // test class 114 // demonstrate the "is a" relationship. 140 141 output += "\n\nCircle c (via circleRef): " + 142 circleRef. c.

Lines 67–111 show a Circle class defi- nition. the keyword override needs to be used in the method declaration.OK. Note that class Point’s ToString method overrides the original ToString from class Object. Note that lines 14 and 21 are comments indicating where the call to the base class Object’s default constructor occurs. 159 MessageBoxButtons. 156 157 MessageBox. Lines 115–163 show a class that demonstrates assigning derived class references to base class references and casting base class references to derived class references. This is specified in the first line of the class definition. 8/7/01 . the public interface to Circle includes the Point public methods as well as the two overloaded Circle constructors and Circle methods Area and © Copyright 1992–2002 by Deitel & Associates. MessageBoxIcon. every derived class constructor is required to call its direct base class’s constructor as its first task either implicitly or explicitly (the syntax for this call is discussed with class Circle momentarily). Operator : in the class declaration indicates inheritance. Lines 7–64 show a Point class definition. All the (non-private) members of class Point (except the constructors) are inherited into class Circle. If the data were specified as private. Inc. 476 Object-Oriented Programming: Part I Chapter 9 153 } 154 else 155 output += "\n\np does not refer to a Circle". 9. In fact. All Rights Reserved. even by derived classes. Class Circle (lines 67–111) inherits from class Point.7 Assigning derived class references to base class references. 160 161 } // end method Main 162 163 } // end class InheritanceTest Fig. we will see that class Circle inherits from class Point.Information ). 158 "Demonstrating the \"is a\" relationship". but enables classes derived from Point to access the inherited instance variables directly. The public services of class Point include methods SetPoint and ToString. Let us first examine the Point class definition in lines 7–64. C# automat- ically attempts to call the base class’s default constructor. Thus. If there is no explicit call to the base class constructor. properties X and Y and two Point constructors. Class Point’s constructors (lines 12–23) by default call class Object’s constructor. The instance variables x and y of Point are specified as pro- tected.Show( output. To do this. This prevents clients of Point objects from directly accessing the data. the non-private methods of Point would have to be used to access the data.

This way. the base reference followed by the dot operator may be used to access the original base class version of that method from the derived class.. call the method.ToString(). As we will soon see. We have actually been overriding methods in several applications in the book. The Circle constructors (lines 72 and 83) must invoke a Point constructor to ini- tialize the base class portion (variables x and y inherited from Point) of a Circle object. Common Programming Error 9. 9.e. This syntax pro- vides a way to explicitly call the base class default constructor. If the Point class contained only the constructor of line 19 (i. All Rights Reserved. Circle method ToString displays the protected instance variables x and y in class Point by calling the base class’s ToString method (in this case. This call is made on line 107 with the expression base. keyword base followed by a set of parentheses containing the arguments to the base class constructor (in this case the values a and b are passed to initialize the base class members x and y)].Chapter 9 Object-Oriented Programming: Part I 477 ToString and the Radius property. Point’s ToString method).ToString() © Copyright 1992–2002 by Deitel & Associates. The call to a base class constructor other than the default one must be part of the opening line in the definition of the derived class constructor.4 It is a syntax error if the arguments to a base call by a derived class to its base class con- structor do not match the parameters specified in one of the base class constructor defini- tions. 8/7/01 . When that method is mentioned by name in the derived class. the values of x and y are used as part of the Circle’s string representation. so C# automatically calls class Point’s default constructor (defined at line 12) that initializes base class members x and y to zeros. When we provided method ToString for many of the classes in Chapter 8. recall our Software Engineering Observation indicating that if a method exists that performs part of another method’s task... This method is used to convert any object of any class into a string representation and is sometimes called implicitly by the program (e.e. Because class Object provides the orig- inal ToString method. so we call Point’s ToString method from class Circle by using the expression base.4 A derived class can redefine a base class method using the same signature. Notice that method Area (line 99–102) uses pre- defined constant Math. did not provide a default constructor). every class inherits a ToString method. Point’s ToString performs part of the task of Circle’s ToString. This is simpler than making Circle’s ToString method use exactly the same formatting as Point’s ToString for the Point parts of the Circle. we were overriding the original version of ToString provided by class Object. Note that class Circle’s ToString method (line 101) overrides the Point class ToString method (line 59). Also. this is called overriding a base class method. when an object is added to a string).PI from class Math to calculate the area of a circle. the derived class version is automatically called. Class Point’s ToString method overrides the original ToString method provided by class Object. a compiler error would occur.g. Inc. Line 80 in the body of the Circle class declares the constructor that explicitly invokes the second Point constructor (defined at line 19) using the base class constructor call syntax [i. The default constructor at line 72 does not explicitly call a Point constructor.

5 Software Engineering Observation 9. Line 139 casts pointRef (which admittedly is referencing a Circle at this time in the program’s execution) to a Circle and assigns the result to circleRef (this cast would be dangerous if pointRef were really referencing a Point. 9. C# knows that the object really is a Circle.4 A redefinition of a base class method in a derived class need not have the same signature as the base class method. All Rights Reserved. Then we use circleRef to append to string output the various facts about Circle circleRef.4 Software Engineering Observation 9. Inc. It is always acceptable in C# to assign a derived class reference to a base class reference (because of the “is a” relationship of inheritance).e. 9. Lines 141–142 invoke method ToString to append the string representation of the Circle. The compiler is simply checking the syntax of the expression and ensuring that the method exists. At execution time. as we will see. See the third line of the screen capture to confirm this. See the first two lines in the output screen capture to confirm this. The two key programming techniques we used to achieve this effect are 1) extending class Point to create class Circle and 2) overriding method ToString with the exact same signature in class Point and class Circle.6 Class InheritanceTest (lines 115–163) instantiates Point object p and Circle object c at lines 123–124 in Main. 9. Line 139 assigns Circle c (a reference to a derived class object) to pointRef (a base class reference). The compiler looks at the preceding expression and asks the question. Lines 133–134 append the result of pointRef. class Circle’s ToString method). when this pointRef is sent the ToString message. This is an example of polymorphism and dynamic binding.ToString() to the string output.5 Any object can be converted to a string with an explicit or implicit call to the object’s ToString method. Point) have a ToString method with no arguments?” The answer to this question is yes (see Point’s ToString definition on line 59).478 Object-Oriented Programming: Part I Chapter 9 Software Engineering Observation 9.Format that formats a number with two digits to the right of the © Copyright 1992–2002 by Deitel & Associates. Such a redefinition is not method overriding but is simply an example of method overloading. Assigning a base class reference to a derived class reference is dangerous. The string representations of each object are appended to string output to show that they were initialized correctly (lines 126– 127).. Interestingly. “What type is the object to which pointRef refers?” Every object in C# knows its own data type (which can be determined using the GetType method). so the answer to the question is pointRef refers to a Circle object. as we will soon dis- cuss). Based on this answer. the interpreter calls the ToString method of the actual object’s data type (i.. the interpreter asks the question.6 Each class should override method ToString to return useful information about objects of that class. concepts we treat in depth later in this chapter. “Does the data type of the reference pointRef (i. so it chooses the Circle ToString method instead of using the Point ToString method as you might have expected. 8/7/01 . Lines 144–145 append the Area of the Circle formatted with method String.e. A Circle is a Point because class Circle extends class Point.

can call base class constructors via the base reference. we are actually specifying what we want to execute when Finalize is called for an object of this class. By creating a destructor for a class. and is therefore a member of all classes.7 If the classes in your class hierarchy define destructor methods. This con- dition evaluates to true only if the object to which p refers is a Circle. All Rights Reserved. Method Finalize is a member of class Object. The format "{0. the base class constructor executes. Because p does not refer to a Circle. 9. Next. C# would determine that p really references a Point. Otherwise. An important point for C# programmers to know is that a destructor is actually another way of overriding an object’s Finalize method. Although we demonstrate destructors in this section.5 Constructors and Destructors in Derived Classes When an object of a derived class is instantiated. recognize the cast to Circle as being dangerous and indicate an improper cast with InvalidCastException message. we pre- vent this statement from executing with the if condition on line 149 that uses methods GetType and typeof to determine if the object to which p refers is a Circle. however. 8/7/01 .InvalidCastException' occurred in followed by the name and path of the executing program.7 When an object of a derived class is created. the condition evaluates to false. An explicit call to the base class constructor (via the base reference) can be provided as a statement in the derived class constructor. otherwise. the base class’s constructor should be called to do any necessary initialization of the base class instance variables of the derived class object. © Copyright 1992–2002 by Deitel & Associates. then the remainder of the derived class constructor’s body executes. the if/else structure at lines 149–155 attempts a dangerous cast in line 151. Derived class construc- tors. class Point and class Circle are simplified. At execution time if this is attempted.Chapter 9 Object-Oriented Programming: Part I 479 decimal point. 9. the derived class destructor should invoke the base class destructor (as its last action) to ensure that all parts of an object are finalized properly when the garbage collector reclaims the memory for the object. Figure 9. first the derived class constructor calls the base class constructor. For the purpose of this example.NET Framework takes care of garbage col- lection for the programmer.5 shows the order in which base class and derived class constructors and destructors are called. the derived class con- structor will call the base class default constructor (or no-argument constructor) implicitly. If we remove the if test from the program and execute the program. We cast Point p to a Circle. the condition fails and a string indicating that p does not refer to a Circle is appended to output.2:F}" (specified at line 145) indicates the proper format- ting for this number. It is also important to note that the . they are often not used in C# classes. However. Software Engineering Observation 9. Base class constructors are not inherited by derived classes. Inc. a MessageBox will be displayed at runtime with the message An unhandled exception of type 'System.

which inherits from Point 41 public class Circle : Point 42 { 43 protected double radius.8 Demonstrating constructors and destructors. 480 Object-Oriented Programming: Part I Chapter 9 Class Point (lines 7–38) contains two constructors. 10 11 // no-argument constructor 12 public Point() 13 { 14 x = 0. 16 Console.cs 2 // A program demonstrating when constructors and 3 // destructors are called. int b ) 21 { 22 x = a. 17 } 18 19 // two-argument constructor 20 public Point( int a.WriteLine calls to cause an implicit call to method ToString. this ). Note the use of this in the Console. 37 } 38 } // end class Point 39 40 // definition of class Circle. " + y + "]". 44 Fig. © Copyright 1992–2002 by Deitel & Associates. 8/7/01 . 4 5 using System. 23 y = b. Notice the first line of the destructor (line 28) ~Point() 1 // Fig. methods ToString and SetPoint and members x and y.8: ConstructorsAndDestructors. Inc. y.WriteLine( "Point destructor: " + this ). 24 Console. 9. this ). 9. 6 7 public class Point 8 { 9 protected int x.WriteLine( "Point constructor: {0}".WriteLine( "Point constructor: {0}". 31 } 32 33 // convert the point into a String representation 34 public override string ToString() 35 { 36 return "[" + x + ". a destructor. 15 y = 0. The constructors each print that they are executing then display the Point for which they are invoked. 25 } 26 27 // destructor 28 ~Point() 29 { 30 Console. All Rights Reserved.

Radius = " + radius. 58 Console. 82 83 circle1 = new Circle( 4.Collect(). 5 ). © Copyright 1992–2002 by Deitel & Associates.WriteLine( "Circle constructor: " + this ). circle2. b ) 55 { 56 // call the base class constructor 57 radius = r. 29 ). 72. 50 Console.GC. 8/7/01 .WriteLine( "Circle constructor: " + this ). 88 circle2 = null. int a. 9. 72 } 73 } // end class Circle 74 75 // class to demonstrate when base class and derived 76 // class constructors are called 77 class Test 78 { 79 static void Main( string[] args ) 80 { 81 Circle circle1.WriteLine( "Circle destructor: " + this ). int b ) : base( a. 91 } 92 93 } // end class Test Fig. Chapter 9 Object-Oriented Programming: Part I 481 45 // no-argument constructor 46 public Circle() 47 { 48 // implicit call to base class constructor here 49 radius = 0. Inc. 5.ToString() + ". 89 90 System.8 Demonstrating constructors and destructors. 84 circle2 = new Circle( 10. All Rights Reserved.5. 66 } 67 68 // convert the Circle to a string 69 public override string ToString() 70 { 71 return "Center = " + base. 51 } 52 53 // three-argument constructor 54 public Circle( double r. 85 86 // mark circle1 and circle2 for garbage collection 87 circle1 = null. 59 } 60 61 // destructor 62 // implicit call to base class destructor occurs 63 ~Circle() 64 { 65 Console.

29]. 9. Since each of these objects is no longer needed. Again. This invokes the Circle constructor at line 54. a ToString method and a protected instance variable radius. Note that the Circle method ToString invokes Point’s ToString via base (line 71).6 Cascading base references to refer to a member (method or variable) several levels up the hierarchy (as in base.8 Demonstrating constructors and destructors. Radius = 0 Circle constructor: Center = [5. Radius = 10 Circle destructor: Center = [5.0 is displayed for the radius because the radius has not yet been initialized in the Circle constructor. C# marks the memory occupied by circle1 and circle2 for garbage collection.5 When a base class method is overridden in a derived class. 5]. Notice that the first two lines of the output from this pro- gram both show values for x. Notice in the command-line output window that the body of the Point constructor is performed before the body of the Circle constructor. The con- structor and destructor each print that they are executing.6 Lines 77–93 show a class that tests this Point/Circle inheritance hierarchy. Radius = 10 Point destructor: Center = [5. 29]. y and radius. When ToString is invoked from the Point constructor. 8/7/01 . Not using the base reference to reference the base class’s method causes infinite recursion because the derived class method actually calls itself. Then the Circle constructor outputs the complete Circle by calling method ToString. The application begins in method Main by instantiating Circle object circle1 (line 83). 29]. Radius = 0 Circle constructor: Center = [72. 5]. 5]. Radius = 4.x) is a syntax error. Class Circle (lines 41–73) derives from Point and contains two constructors. 29]. Common Programming Error 9. All Rights Reserved. Circle object circle2 is instantiated next. Radius = 10 Circle destructor: Center = [72. showing that objects are constructed “inside out.5 Point constructor: Center = [5. Polymorphism is once again causing the Circle’s ToString method to execute because it is a Circle object that is being cre- ated. a destructor. 9. the Point and Circle con- structors both execute. 0.5 Common Programming Error 9. then display the Circle for which they are invoked.5 Fig. 5].” Lines 87–88 set circle1 to null then set circle2 to null. Radius = 4.base. which immediately invokes the Point constructor at line 20.5 Point destructor: Center = [72. The garbage collector is a low-priority thread that runs automatically whenever processor time is available. C# guarantees that before the garbage collector runs to reclaim the space for each of these objects. Inc. the destructor methods for each object will be called. 482 Object-Oriented Programming: Part I Chapter 9 Point constructor: Center = [72. We choose here to force the garbage collector to run with the call © Copyright 1992–2002 by Deitel & Associates. 9. it is common to have the derived class version call the base class version and do some additional work. Radius = 4. The Point constructor outputs the values received from the Circle constructor by implicitly calling method ToString and returns program control to the Circle constructor.

we would like to be able to walk through an array of employees and calculate the weekly pay for each person.GC. and to do this by manipulating all these objects with base class references.6 Implicit Derived-Class-Object to Base-Class-Object Conversion Despite the fact that a derived class object also “is a” base class object. © Copyright 1992–2002 by Deitel & Associates. This makes sense because the derived class has members corresponding to each of the base class members—remember that the derived class normally has more members than the base class has. There are four possible ways to mix and match base class references and derived class references with base class objects and derived class objects: 1. the derived class type and the base class type are different. Notice in the command-line output window that both the Circle and Point destructor methods are called when each Circle object is garbage collected. Referring to a derived class object with a derived class reference is straightfor- ward. 4. Actually. The derived class reference must first be cast to a base class reference. C# does not guarantee when or how often objects will be garbage collected. it cannot guarantee which object’s destructor will execute first. Common Programming Error 9. Referring to a base class object with a base class reference is straightforward.7 Assigning a derived class object to a base class reference. 8/7/01 . therefore. Referring to a derived class object with a base class reference is safe because the derived class object is an object of its base class as well. there appears to be a problem. and then attempting to reference derived class-only members with the base class reference.GC. Derived class objects can be treated as base class objects. whether it is a base class object or a derived class object. Such code can only refer to base class members. for example. But intuition suggests that using base class references would enable the program to call only the base class payroll cal- culation routine (if indeed there is such a routine in the base class). A reference to a derived class object may be implicitly converted into a reference to a base class object because a derived class object is a base class object through inheritance. Assignment in the other direction is not allowed because assigning a base class object to a derived class reference would leave the additional derived class members undefined.Collect in line 90.7 As convenient as it may be to treat derived class objects as base class objects. We need a way to invoke the proper payroll calculation routine for each object. Inc. Referring to a base class object with a derived class reference is a syntax error. In a payroll system. and to do this simply by using the base class reference. this is precisely how C# behaves and is discussed in the next chapter when we consider poly- morphism and dynamic binding. We use System. is a syntax error. 3. 2. All Rights Reserved. the compiler will report a syntax error. 9.Collect when we want to free-up memory by eliminating unnecessary objects. If this code refers to derived class-only members through the base class reference. 9.Chapter 9 Object-Oriented Programming: Part I 483 System.

Software Engineering Observation 9.7 Software Engineering with Inheritance We can use inheritance to customize existing software. too. 8/7/01 . 9. but such classes might be too rich for certain users.1 Note that reading a set of derived class declarations can be confusing because inherited members are not shown.10 © Copyright 1992–2002 by Deitel & Associates. Object-oriented programming in general. interest in C# class libraries will increase.10 In an object-oriented system. As interest in C# grows.9 Performance Tip 9. Derived classes are then customized beyond the capabilities inherited from the base class. each providing substantial ad- ditional functionality.8 A base class specifies commonality. the new class inherits the attributes and behaviors of an existing class.484 Object-Oriented Programming: Part I Chapter 9 9. certainly does this. 9. In the object-oriented design process. Software Engineering Observation 9. then we can add attributes and behaviors or override base class behaviors to customize the class to meet our needs. A similar problem can exist in the documentation of derived classes. memory and pro- cessing resources may be wasted. 9. All Rights Reserved. “Factor out” common at- tributes and behaviors and place these in a base class. Proliferating classes creates management problems and can hinder software re- usability simply because it is more difficult for a potential user of a class to locate that class in a huge collection. Inc.1 If classes produced through inheritance are larger than they need to be. It can be difficult for students to appreciate the problems faced by designers and implementers on large-scale software projects in industry. Then use inheritance to form derived classes without having to repeat common attributes and behaviors. Application designers will build their applications with these libraries. It is the availability of substantial and useful class libraries that delivers the maximum benefits of software reuse through inheritance. All classes derived from a base class inherit the capabilities of that base class. and library designers will be rewarded by having their libraries wrapped with the applications. so. 9.9 Just as the designer of non-object-oriented systems should avoid unnecessary proliferation of functions. What we see coming is a massive worldwide com- mitment to the development of C# class libraries for a huge variety of applications arenas. When we use inheritance to create a new class from an existing class. classes are often closely related. will the creation and sale of C# class libraries. Software Engineering Observation 9.8 Creating a derived class does not affect its base class's source code or the base class’s MSIL. the integrity of a base class is preserved by inheritance. the designer of object-oriented systems should avoid unnecessary proliferation of classes. Inherit from the class “closest” to what you need. Just as shrink-wrapped software produced by independent software vendors became an explosive growth industry with the arrival of the personal computer. and C# in particular. the designer looks for commonality among a set of classes and factors it out to form desirable base classes. but inherited members are nevertheless present in the derived classes. People experienced on such projects will invariably state that a key to improving the software development process is encouraging software reuse. The trade-off is to create fewer classes.

10). We have also discussed has a relationships (and seen examples in preceding chapters) in which a class may have objects of other classes as members—such relationships create new classes by composition of existing classes. we present an example in which we derive class Cylinder from class Circle (Fig.9 shows class Point. int b ) 21 { 22 SetPoint( a.14). 9. Figure 9. Circle. 17 } 18 19 // two-argument constructor 20 public Point( int a.11 Modifications to a base class do not require derived classes to change as long as the public interface to the base class remains unchanged. Circle. 9. Then we present an example in which we derive class Circle from class Point (Fig.cs 2 // Definition of class Point. 6 7 namespace PointNamespace 8 { 9 public class Point 10 { 11 protected int x. 9. 9.9: Point. All Rights Reserved. b ). // coordinates of the point 12 13 // no-argument constructor 14 public Point() 15 { 16 SetPoint( 0.8 Composition vs. y. Cylinder hierarchy. Part 1 is the class Point definition. 9. Inheritance We have discussed is a relationships that are implemented by inheritance. Inc. the methods of class Circle will be able to directly reference coordinates x and y rather than using access methods. 9.11 and Fig.9 and Fig.9 Class Point.9 Case Study: Point. 9. circle. We consider a point. 9. 1 // Fig. given the classes Employee.11 9.12). 4 5 using System. Thus.13 and Fig. This may result in better performance. 8/7/01 . cylinder hierarchy. 0 ). Note that Point’s instance variables are protected. 9. © Copyright 1992–2002 by Deitel & Associates. when class Circle is derived from class Point. 9. Fig. But it is certainly appropriate to say that an Employee has a BirthDate and that an Employee has a TelephoneNumber. Cylinder Now let us consider a substantial inheritance example. it is improper to say that an Employee is a BirthDate or that an Employee is a TelephoneNumber. BirthDate and TelephoneNumber. For example. First we develop and use class Point (Fig. the root in our 3 // Point. Chapter 9 Object-Oriented Programming: Part I 485 Software Engineering Observation 9. Finally.

486 Object-Oriented Programming: Part I Chapter 9 23 } 24 25 // set x and y coordinates of the Point 26 public void SetPoint( int a. Inc.9 Class Point. " + y + "]". 29 Y = b. 5 using System.cs 2 // A driver to test class Point. 37 } 38 set 39 { 40 x = value.Forms. Fig. 9. 8/7/01 . 3 4 using System.10 Testing class Point. 41 } 42 } 43 44 public int Y 45 { 46 get 47 { 48 return y. 9. © Copyright 1992–2002 by Deitel & Associates. 53 } 54 } 55 56 // convert the point into a String representation 57 public override string ToString() 58 { 59 return "[" + x + ". 1 // Fig.Windows. int b ) 27 { 28 X = a. 30 } 31 32 public int X 33 { 34 get 35 { 36 return x. All Rights Reserved. 49 } 50 set 51 { 52 y = value. 6 using PointNamespace. 60 } 61 62 } // end class Point 63 64 } // end namespace PointNamespace Fig.10: PointTest. 9.

Chapter 9 Object-Oriented Programming: Part I 487 7 8 namespace PointTest 9 { 10 class PointTest 11 { 12 static void Main( string[] args ) 13 { 14 Point p = new Point( 72. 9. 27 MessageBoxButtons.11 Class Circle. 28 29 } // end method Main 30 31 } // end class PointTest 32 33 } // end namespace PointTest Fig. Figure 9. 22 23 // use implicit call to p. Fig. 20 21 p.Y. we see the definition for class Circle. 9.Show( output. 4 5 using System. 25 26 MessageBox.12 shows a CircleTest application. note the implicit call to ToString when p is added to a string at line 24. 10 ).11: Circle.cs 2 // Definition of a Circle class with inherits 3 // from our Point class. "Demonstrating Class Point".SetPoint( 10.OK. 8/7/01 . Inc.Information ).X + 19 "\nY coordinate is " + p. 16 17 // displaying the properties of our Point 18 output = "X coordinate is " + p. In our next example. The Main method must use properties X and Y to read the values of protected instance variables x and y. 9. their derived classes and other classes in the same package.10 shows a PointTest application for testing class Point. 115 ). Also. 15 string output. Figure 9. All Rights Reserved. MessageBoxIcon. © Copyright 1992–2002 by Deitel & Associates. Remember that protected instance variables are accessible only to methods of their class.ToString() 24 output += "\n\nThe new location of p is " + p.10 Testing class Point. 1 // Fig.

7 // we need to include the namespace for our Point class 8 9 namespace CircleNamespace 10 { 11 public class Circle : Point 12 { 13 protected double radius. 45 } 46 47 // convert the Circle to a String 48 public override string ToString() 49 { 50 return "Center = " + base. 488 Object-Oriented Programming: Part I Chapter 9 6 using PointNamespace. 8/7/01 .ToString() + ". int a.11 Class Circle. 27 } 28 29 public double Radius 30 { 31 get 32 { 33 return radius. 38 } 39 } 40 41 // calculate the area of Circle 42 public virtual double Area() 43 { 44 return Math. Radius = " + 51 radius. 52 } 53 54 } // end class Circle 55 56 } // end namespace CircleNamespace Fig. All Rights Reserved. © Copyright 1992–2002 by Deitel & Associates. b ) 24 // call the base-class constructor 25 { 26 Radius = r. Inc. 14 15 // no-argument constructor 16 public Circle() 17 { 18 // implicit call to base class constructor here 19 Radius = 0. 34 } 35 set 36 { 37 radius = value. 20 } 21 22 // three-argument constructor 23 public Circle( double r.PI * Radius * Radius. int b ) : base( a. 9.

12 Testing class Circle.Radius. 8/7/01 . Inc.Show( output.SetPoint( 2. Chapter 9 Object-Oriented Programming: Part I 489 1 // Fig. Note that class Circle extends class Point.ToString( "f" ). 37. 17 18 // access the properties of our Circle 19 output = "X coordinate is " + c. 22 23 c. 2 ). 24 c.Information ).Area(). 25 26 // calculate and print the information for our Circle 27 output += "\n\nThe new location and radius of c are\n" 28 + c + "\nArea is " + c.Y + 21 "\nRadius is " + c. 16 string output. 8 9 namespace CircleTest 10 { 11 class CircleTest 12 { 13 static void Main( string[] args ) 14 { 15 Circle c = new Circle( 2. 3 4 using System.25.Forms.12: CircleTest. This means that the public interface to Circle includes the Point methods as well as the Circle methods Area and © Copyright 1992–2002 by Deitel & Associates.Windows. MessageBoxIcon. 5 using PointNamespace.cs 2 // A driver to test our Circle class.OK.5. All Rights Reserved. "Demonstrating Class Circle". 6 using CircleNamespace. 9. 7 using System. 32 } 33 34 } // end class CircleTest 35 36 } // end namespace CircleTest Fig.X + 20 "\nY Coordinate is " + c. 29 30 MessageBox. 9. 31 MessageBoxButtons.Radius = 4. 43 ).

6 using PointNamespace. 9. Data abstraction. 9. 9.12) instantiates an object of class Circle (line 15). Both override and virtual will be discussed in more detail in Chapter 10. Application CircleTest (Fig. Cylinder. The CylinderTest application’s Main method instantiates an object of class Cylinder (line 14).13: Cylinder. Inc. Method Main then uses properties again to reset the radius and coordinates of the center of the circle. Method Main indirectly references the protected data of class Circle through method calls. the CylinderTest application’s Main method cannot directly reference the protected data of class Cylinder. Then Main uses ToString. Cylinder methods Area (which overrides the Circle area method). Method Main uses properties Height and Radius and method SetPoint to reset the Height. All Rights Reserved. Finally. Area and Volume to print the attributes and some facts about the Cylinder.13 Class Cylinder. inheritance and polymorphism are the crux of object-oriented programming. which inherits 3 // from class Circle. 9. 8 9 namespace CylinderNamespace 10 { 11 public class Cylinder : Circle 12 { 13 protected double height. The reader should now be confident with the basics of inher- itance. 490 Object-Oriented Programming: Part I Chapter 9 ToString. Main displays the Circle object c and calculates and displays its area.13. Again. 8/7/01 .14 is a CylinderTest application to test the Cylinder class. Radius and coordinates of the Cylinder. we show how to program with inheritance hierarchies in a general manner using polymorphism. 1 // Fig.cs 2 // Definition of class Cylinder. This means that the public interface to Cylinder includes the Circle methods and Point methods as well as the Cylinder constructor. // height of cylinder 14 15 // no-argument constructor 16 public Cylinder() 17 { 18 // implicit call to base-class constructor 19 Height = 0. 7 using CircleNamespace. This example nicely demonstrates inheritance and defining and referencing pro- tected instance variables. Figure 9. 4 5 using System. In the next several sections. is shown in Fig. 20 } Fig. then uses properties to obtain the information about the Circle object. Object-Oriented Programming: Part 2. then uses properties (lines 18–21) to obtain infor- mation about the Cylinder object. the property Radius and the Circle constructors. © Copyright 1992–2002 by Deitel & Associates. Notice that method Area is declared virtual on line 42. The definition of our last class. Note that class Cylinder extends class Circle. The keyword virtual is used to indicate that a class can be overridden using the override keyword. Volume and ToString and the property Height.

47 } 48 49 // calculate the volume of Cylinder 50 public double Volume() 51 { 52 return base. 27 } 28 29 // property Height 30 public double Height 31 { 32 get 33 { 34 return height.cs 2 // A driver to test class Cylinder. © Copyright 1992–2002 by Deitel & Associates.PI * radius * Height. 8/7/01 . Height = " + Height. All Rights Reserved.14 Testing class Cylinder. 35 } 36 set 37 { 38 height = ( value >= 0 ? value : 0 ).. surface area ) 43 public override double Area() 44 { 45 return 2 * base.Area() + 46 2 * Math. 9. 9. Chapter 9 Object-Oriented Programming: Part I 491 21 22 // four-argument constructor 23 public Cylinder( double h. a. int b ) : 24 base( r. 5 using PointNamespace. double r.Area() * Height.ToString() + ". int a. b ) 25 { 26 Height = h. 59 } 60 61 } // end class Cylinder 62 63 } // end namespace CylinderNamespace Fig. Inc. 39 } 40 } 41 42 // calculate area of Cylinder ( i.13 Class Cylinder. 53 } 54 55 // convert the Cylinder to a string 56 public override string ToString() 57 { 58 return base.e. 3 4 using System. Fig. 1 // Fig.14: CylinderTest. 9.

Radius = 4. 8 using System. All Rights Reserved. 13 ). Inc.Height = 10. 15 string output. 492 Object-Oriented Programming: Part I Chapter 9 6 using CircleNamespace.Y + 20 "\nRadius is " + c.10 Case Study: Creating and Using Interfaces Our next example reexamines the Point. 2. "Demonstrating Class Cylinder". 8/7/01 .OK.Height. 22 23 c. 26 27 // calculating and displaying the area and 28 // volume of our Cylinder 29 output += 30 "\n\nThe new location. 7 using CylinderNamespace.Radius + 21 "\nHeight is " + c. 9.ToString( "f" ) + 33 "\nVolume is " + c.SetPoint( 2. Circle. 36 MessageBoxButtons. 12.14 Testing class Cylinder.X + 19 "\nY coordinate is " + c. 9 10 class CylinderTest 11 { 12 static void Main( string[] args ) 13 { 14 Cylinder c = new Cylinder( 5. 9.ToString( "f" ).Windows. 25 c.Forms. radius " + 31 "and height of c are\n" + c + 32 "\nArea is " + c. 2 ). 37 } 38 39 } // end class CylinderTest Fig.25. Cylinder. 16 17 // displaying the property values for our Cylinder 18 output = "X coordinate is " + c.Area().Information ). MessageBoxIcon. An interface definition begins with the keyword interface and © Copyright 1992–2002 by Deitel & Associates. 24 c.7.5. 34 35 MessageBox.Volume(). this time to demonstrate the use of an interface.Show( output.

9. returning the value 0. The definition of interface IShape begins at line 5 of Fig. If the class leaves one method in the interface undefined. Classes Point2. Method GetName is defined at line 76. One benefit of using interfaces is that a class can implement as many interfaces as it needs in addition to extending a class. However.1 Line 10 indicates that class Point2 implements interface Shape. Circle2 and Cylinder2 are quite similar to Point. When a class implements an interface. These three methods satisfy the implementation requirement for the three methods defined in the interface. simply pro- vide a comma-separated list of interface names after operator : in the class definition. Method Volume is defined at line 70.0. Inc. class Point2 implements IShape. Notice that the Object method ToString is called through an IShape refer- ence (line 44 of Fig. that version of the method will be called whenever a Circle2 object calls Volume. the same is a relationship provided by inherit- ance applies. and class Cylinder2 inherits from Circle2. an error is generated. 9. Class Point2 provides definitions of all three methods in the interface. By coincidence.19). a class must specify that it implements the interface (by inheriting it) and the class must define every method in the interface with the number of arguments and the return type specified in the interface definition.12 All methods of class Object can be called using a reference of an interface data type—a reference refers to an object and all objects have the methods defined by class Object. objects of any class that extends Point2 are also IShape objects. Interfaces are typically public data types.e. © Copyright 1992–2002 by Deitel & Associates. All Rights Reserved. no instance variables and no default method implementations.8 Leaving a method of an interface undefined in a class that implements the interface re- sults in a compile error. To implement more than one interface. all three methods take no arguments. Method Area is defined at line 64.15. 9. To use an interface. so we focus on the new concepts here.. 9. a Point2 object is a IShape. Line 47 of Fig. We have fulfilled our contract with the compiler. Why was no error generated? The reason is that if this class is defined in a base class of Circle2. that class Circle2 does not define method Volume. In our example. 9. Good Programming Practice 9.12 Class Circle2 inherits from Point2.Chapter 9 Object-Oriented Programming: Part I 493 contains a list of methods. Implementing a inter- face is like signing a contract with the compiler that states. 9. In fact. Both classes implicitly implement IShape. Volume and GetName.19 calls the Volume method for all the objects defined in this example. In the case of our Circle2 object. “I will define all the methods specified by the interface. Therefore. The reader may notice.8 An interface is typically used when there is no default implementation to inherit—i. this is not a requirement of methods in an interface. Interface IShape has methods Area. Software Engineering Observation 9.1 It is common in C# programming to begin the name of an interface with a capital “I”. however. Circle and Cylinder in the last section. the Volume method of class Point2 is called.” Common Programming Error 9. 8/7/01 .

which implements IShape. 4 5 using System. 7 8 namespace Point2Namespace 9 { 10 public class Point2 : IShape 11 { 12 protected int x. y. 7 8 namespace ShapeNamespace 9 { 10 public interface IShape 11 { 12 // these methods MUST be defined by 13 // any classes the implement IShape 14 double Area(). 4 // Cylinder hierarchy. // coordinates of the point 13 14 // no-argument constructor 15 public Point2() 16 { 17 SetPoint( 0. © Copyright 1992–2002 by Deitel & Associates. 18 } 19 20 // two-argument constructor 21 public Point2( int a. 9. b ). 0 ). int b ) 22 { 23 SetPoint( a. 24 } 25 Fig. 16 string GetName().cs 2 // Definition of our Shape interface.16 Definition of class Point2. 494 Object-Oriented Programming: Part I Chapter 9 1 // Fig. 6 using ShapeNamespace. which 3 // inherits from interface IShape. 15 double Volume(). Circle. 5 6 using System.cs 2 // Definition of class Point. 8/7/01 . 17 18 } // end interface IShape 19 20 } // end namespace ShapeNamespace Fig. 9. 1 // Fig. 9. 3 // which we will use in our Point. All Rights Reserved.15: ShapeInterface.16: Point2. 9.15 Interface IShape. Inc.

42 } 43 } 44 45 public int Y 46 { 47 get 48 { 49 return y. 50 } 51 set 52 { 53 y = value. 8/7/01 . Inc. 67 } 68 69 // return the volume 70 public virtual double Volume() 71 { 72 return 0. 38 } 39 set 40 { 41 x = value. All Rights Reserved. which implements IShape. 61 } 62 63 // return the area 64 public virtual double Area() 65 { 66 return 0. Chapter 9 Object-Oriented Programming: Part I 495 26 // set x and y coordinates of the Point 27 public void SetPoint( int a. int b ) 28 { 29 X = a. 31 } 32 33 public int X 34 { 35 get 36 { 37 return x.0. 79 } Fig.0. 73 } 74 75 // return the class name 76 public virtual string GetName() 77 { 78 return "Point". " + y + "]". 54 } 55 } 56 57 // convert the point into a String representation 58 public override string ToString() 59 { 60 return "[" + x + ". 9.16 Definition of class Point2. © Copyright 1992–2002 by Deitel & Associates. 30 Y = b.

9.17: Circle2.16 Definition of class Point2. 6 using ShapeNamespace. 14 15 // no-argument constructor 16 public Circle2() 17 { 18 // implicit call to base class constructor here 19 Radius = 0. Fig. All Rights Reserved. 1 // Fig. b ) 24 // call the base-class constructor 25 { 26 Radius = r. 34 } 35 set 36 { 37 radius = value.cs 2 // Definition of a Circle class that inherits from Point. © Copyright 1992–2002 by Deitel & Associates. 38 } 39 } 40 41 // calculate the area of Circle 42 public override double Area() 43 { 44 return Math. 20 } 21 22 // three-argument constructor 23 public Circle2( double r. 8 9 namespace Circle2Namespace 10 { 11 public class Circle2 : Point2 12 { 13 protected double radius. 8/7/01 . int a. 27 } 28 29 public double Radius 30 { 31 get 32 { 33 return radius. int b ) : base( a. 4 5 using System. which implements IShape. 3 // Class Point itself inherits from the Shape interface. 9. Inc. 9.17 Definition of class Circle2. 7 using Point2Namespace.PI * Radius * Radius. 496 Object-Oriented Programming: Part I Chapter 9 80 81 } // end class Point2 82 83 } // end namespace Point2Namespace Fig.

22 } 23 24 // four-argument constructor 25 public Cylinder2( double h. Cylinder 4 // hierarchy that uses interface Shape. b ) 27 { 28 Height = h. 5 6 using System. 8/7/01 .18: Cylinder2. 9 using Circle2Namespace. 8 using Point2Namespace.cs 2 // Definition of class Cylinder. int b ) : 26 base( r. Radius = " + 51 radius. 52 } 53 54 // return the class name 55 public override string GetName() 56 { 57 return "Circle". 9. Inc. // height of cylinder 16 17 // no-argument constructor 18 public Cylinder2() 19 { 20 // implicit call to base-class constructor 21 Height = 0. 58 } 59 60 } // end class Circle2 61 62 } // end class Circle2Namespace Fig. 9. double r. All Rights Reserved. the last 3 // class in the Point. a. 29 } 30 Fig.17 Definition of class Circle2. 9. int a. 7 using ShapeNamespace.ToString() + ".18 Definition of class Cylinder2. Chapter 9 Object-Oriented Programming: Part I 497 45 } 46 47 // convert the Circle to a String 48 public override string ToString() 49 { 50 return "Center = " + base. 10 11 namespace Cylinder2Namespace 12 { 13 public class Cylinder2 : Circle2 14 { 15 protected double height. © Copyright 1992–2002 by Deitel & Associates. 1 // Fig. Circle.

Height = " + Height. 7 using ShapeNamespace. 4 5 using System. Cylinder 3 // hierarcy which inherits from an interface. 498 Object-Oriented Programming: Part I Chapter 9 31 // property Height 32 public double Height 33 { 34 get 35 { 36 return height.19: InterfaceTest. 49 } 50 51 // calculate the volume of Cylinder 52 public override double Volume() 53 { 54 return base.Area() * Height.ToString() + ". 55 } 56 57 // convert the Cylinder to a string 58 public override string ToString() 59 { 60 return base. 8/7/01 . 61 } 62 63 // return the class name 64 public override string GetName() 65 { 66 return "Cylinder". 9. 1 // Fig.Area() + 48 2 * Math.18 Definition of class Cylinder2. 9.. 67 } 68 69 } // end class Cylinder2 70 71 } // end namespace Cylinder2Namespace Fig. 37 } 38 set 39 { 40 height = ( value >= 0 ? value : 0 ). © Copyright 1992–2002 by Deitel & Associates. Fig.e. Inc. 6 using System.Forms. 41 } 42 } 43 44 // calculate area of Cylinder ( i.Windows.19 Testing a class hierarchy that uses an interface as its base. Circle. 9. All Rights Reserved.cs 2 // A driver to test the Point. surface area ) 45 public override double Area() 46 { 47 return 2 * base.PI * radius * Height.

17 Circle2 circle = new Circle2( 3.GetName() + ": " + circle.Volume(). 39 // area and volume for each object 40 for ( int i = 0.OK. © Copyright 1992–2002 by Deitel & Associates.19 Testing a class hierarchy that uses an interface as its base. 29 30 // aim arrayOfShapes[ 2 ] at Cylinder object 31 arrayOfShapes[ 2 ] = cylinder. 10.5. i < arrayOfShapes.GetName() + ": " + point.Length. 11 12 class Test 13 { 14 static void Main( string[] args ) 15 { 16 Point2 point = new Point2( 7. 10 ). 48 } 49 50 MessageBox. 9. Chapter 9 Object-Oriented Programming: Part I 499 8 using Point2Namespace. 26 27 // aim arrayOfShapes[ 1 ] at Circle object 28 arrayOfShapes[ 1 ] = circle. 51 MessageBoxButtons. 3. 37 38 // loop through arrayOfShapes and print the name. 10 using Cylinder2Namespace.GetName() + ": " + cylinder. 52 53 } // end method Main 54 55 } // end class Test Fig.3.GetName() + ": " + 44 arrayOfShapes[ i ]. 22. 32 33 string output = 34 point. i++ ) 41 { 42 output += "\n\n" + 43 arrayOfShapes[ i ].ToString( "f" ). 23 24 // aim arrayOfShapes[ 0 ] at Point object 25 arrayOfShapes[ 0 ] = point.Information ). Inc. 18 Cylinder2 cylinder = new Cylinder2( 10.ToString() + "\n" + 35 circle.ToString().Area().ToString( "f" ) + 46 "\nVolume = " + 47 arrayOfShapes[ i ]. 8/7/01 . 19 20 IShape[] arrayOfShapes. MessageBoxIcon. All Rights Reserved.ToString() + "\n" + 36 cylinder.ToString() + "\nArea = " + 45 arrayOfShapes[ i ]. 11 ). "Demonstrating Polymorphism". 9 using Circle2Namespace. 8 ).Show( output. 21 22 arrayOfShapes = new IShape[ 3 ].

All Rights Reserved. 8/7/01 . 9. Inc. 500 Object-Oriented Programming: Part I Chapter 9 Fig. © Copyright 1992–2002 by Deitel & Associates.19 Testing a class hierarchy that uses an interface as its base.

• Please be constructive. grammatical errors. errors or omissions in the chapter discussions. • Please check that there are no inconsistencies. Please send us a short e-mail if you would like to make such a suggestion. This book will be published soon. © Copyright 1992–2002 by Deitel & Associates.yaeger@dei- tel. • Please read all of the back matter including the exercises and any solutions we provide. • Please review the index we provide with each chapter to be sure we have covered the topics you feel are important. All Rights Reserved. • The manuscript is being copyedited by a professional copy editor in parallel with your reviews. We will not make significant adjustments to our writing style on a global scale. • Please do not rewrite the manuscript. We all want to publish the best possible book. We are concerned mostly with technical correctness and cor- rect use of idiom. Inc. • Please run all the code examples. 8/7/01 .net. • If you find something that is incorrect.Chapter 9 Object-Oriented Programming: Part I 501 [***Notes To Reviewers***] • Please feel free to send any lengthy additional comments by e-mail to cheryl. • Please check that we are using the correct programming idioms. spelling errors. That person will probably find most typos. etc. please show us how to correct it.

463 Math. 8/7/01 . destructors are called 479 463 base class constructor 476 G overloaded constructors 476 garbage collector 479 overloading 478 base class constructor call syntax 477 override method ToString 478 overriding 477 base class default constructor 479 H overriding a base class method base class destructor 479 “has a” relationship 461 base class method is overridden in 477 hierarchy diagram 463 overriding methods 477 a derived class 482 base class objects 472 base class reference 472. member access operator 465. 479.) operator 465. 477 object-oriented programming assigning derived class references dynamic binding 478. 477 implicitly converted into 479 multiple inheritance 460 reference to base class object derived class object is a base class 483 object through inheritance referring to a base class object 483 N with a base class reference derived class reference 472 no-argument constructor 479 483 © Copyright 1992–2002 by Deitel & Associates. 483 (OOP) 460 to base class references 476 objects constructed “inside out” attributes (data) 484 E 482 employees 483 OOP (Object-oriented B extending a class 493 Programming) 460 order in which constructors and base class 459. 462. 464 base reference 477. 490 476 information hiding 461 predefined constant 477 base class’s private members inheritance 460. 463. 461. 478 convert a base class reference to a derived class 464 derived class reference 472 public interface 489 L public members of a derived low-priority thread 482 class 464 D dangerous cast 479 data abstraction 490 M R default constructor 476. 460. 461. 483. 490 private members of a base 464 inheritance (:) operator 460 class 463 base class’s protected inheritance examples 462 members 464 project access 465 inheritance hierarchy 463.Index 1 Symbols derived class-object-is-a-base O class-object relationship : inheritance operator 460 object of a base class 472 461 object of a derived class 472 destructor 479 object of a derived class is A direct base class 460 instantiated 479 abstraction 461 dot (.PI 477 reference to a derived class object derived class constructor 476. 487 Cascading base references 482 protected internal 463 cast operation 472 member access 465 internal member access 465 class libraries 462. All Rights Reserved. Inc. 478. 485 class 464 472. 479 constructor 482 protected members of a “is a” relationship 461. 479 Math class 477 rectangle 462 derived class 460. 462. 484 protected members of a base InvalidCastException composition 461. 484. 482 protected access 461 inherited instance variables 476 behaviors 484 protected base class members instance variable 476 461 interface data type 493 protected instance variable interfaces 460 C internal access modifier 461. I P 483 implement many interfaces 493 parallelogram 462 base class’s constructor 479 implements an interface 493 payroll system 483 base class’s default constructor indirect base class 463 polymorphism 478. 477.

All Rights Reserved. Inc. 478 single inheritance 460 software reusability 460 software reuse 484 square 462 standard reusable components 462 superclass’s protected members 465 switch structure 461 T thread 482 trapezoid 462 © Copyright 1992–2002 by Deitel & Associates. 8/7/01 .2 Index referring to a base class object with a derived class reference 483 referring to a derived class object with a base class reference 483 referring to a derived class object with a derived class reference 483 reusable components 462 S same signature 478 Shape class hierarchy 464 Shape hierarchy 463 signature 477.