understanding inheritance object-oriented programming using c++ second edition 9

66
Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Post on 21-Dec-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance

Object-Oriented Programming Using C++

Second Edition

9

Page 2: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Objectives

• In this chapter, you will learn:

• About inheritance and its benefits

• How to create a derived class

• About restrictions imposed with inheritance

• How to choose a class access specifier

• How to override and overload parent class functions within a child class

• How to use a constructor initialization list

9

Page 3: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Objectives

• In this chapter, you will learn:

• How to provide for a base class constructor within a derived class

• How to override the class access specifier

• How to use multiple inheritance

• About the special problems posed by multiple inheritance

• How to use virtual inheritance

9

Page 4: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance

• Objects used in computer programs also are easier to understand if you can place them within a hierarchy of inheritance

• Suppose you have written several programs with a class named Student

• The FirstYearStudent class inherits from the Student class, or is derived from it

• The Student class is called a parent class, base class, superclass, or ancestor; the FirstYearStudent class is called a child class, derived class, subclass, or descendant

• When you override a function, you substitute one version of the function for another

9

Page 5: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding the Advantages Provided by Inheritance

• Inheritance is considered a basic building block of object-oriented programming

• Programs in which you derive new classes from existing classes offer several advantages:

– You save time because much of the code needed for your class is already written

– You save additional time because the existing code has already been tested—that is, you know it works correctly; it is reliable

9

Page 6: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding the Advantages Provided by Inheritance

• Advantages of using derived classes:

– You save even more time because you already understand how the base class works, and you can concentrate on the complexity added as a result of your extensions to the class

– In a derived class, you can extend and revise a parent class without corrupting the existing parent class features

– If other classes have been derived from the parent class, the parent class is even more reliable—the more its code has been used, the more likely it is that logical errors have already been found and fixed

9

Page 7: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class

• The class, named Person, is shown in Figure 9-1• It contains three fields, and two member functions that set

and display the data field values

9

Page 8: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class

• To create a derived class, you include the following elements in the order listed:– Keyword class

– Derived class name

– Colon

– Class access specifier, either public, private, or protected

– Base class name

– Opening brace

– Class definition statements

– Closing brace

– Semicolon

9

Page 9: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class

• The Customer class shown in Figure 9-2 contains all the members of Person because it inherits them

9

Page 10: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The Customer Class

9

Page 11: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class9

Page 12: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class

• In the set of steps outlined on pages 317 to 319 of the textbook, you create two classes, Car and Convertible

• The Car class serves as a base class and includes features common to all cars

9

Page 13: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Creating a Derived Class

• You create the Convertible class and a demonstration program in the steps referred to on pages 319 and 320 of the textbook

9

Page 14: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance Restrictions

• Figure 9-8 shows a modified version of the Customer class outputBalDue() function, originally presented in Figure 9-3

• The improvement lies in the addition of the Customer ID number to the explanation of the output

• However, if you replace the original outputBalDue() function with the one shown in Figure 9-8, programs that use the function no longer run

• The error message states that idNum is inaccessible; that is, the Customer class function cannot use it

9

Page 15: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance Restrictions

• When a class serves as a base class to other classes, all of its members can be used within the child class functions, except for private members

• While having private members is a good idea, it often is inconvenient

• There are times when you want a child class object to be able to access private data members that it owns, but that originated with the parent

• Fortunately, C++ provides an alternative to private and public specifiers

9

Page 16: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance Restrictions

• The protected specifier allows members to be used by class member functions and by derived classes, but not by other parts of a program

9

Page 17: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding Inheritance Restrictions

• A child class function cannot use its parent class’s constructor

• The following are never inherited:

– Constructor functions

– Destructor functions

– Friend functions

– Static data members

– Static member functions

– Overloaded new operators

– Overloaded = operators

9

Page 18: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• C++ programmers usually use the public access specifier for inheritance

• If a derived class uses the public access specifier, then the following statements are true:

– Base class members that are public remain public in the derived class

– Base class members that are protected remain protected in the derived class

– Base class members that are private are inaccessible in the derived class

9

Page 19: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• If a derived class uses the protected access

specifier, then the following statements are true:

– Base class members that are public become protected

in the derived class

– Base class members that are protected remain

protected in the derived class

– Base class members that are private are inaccessible in

the derived class

9

Page 20: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• If a derived class uses the private access

specifier, then the following statements are true:

– Base class members that are public become private in

the derived class

– Base class members that are protected become private

in the derived class

– Base class members that are private are inaccessible in

the derived class

9

Page 21: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• Figure 9-10 shows a class named DemoBasePerson that contains three data members

• For illustration, one field is private, another is protected, and the third field is public

• The setPerson() and showPerson() functions also are public

9

Page 22: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

9

Page 23: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• The two highlighted and commented cout statements in Figure 9-11 are not correct

• If you remove the comment designation from either of these statements, the program does not compile

• The DemoBasePerson class fields age and salary are not accessible from within the main() program because they are not public

• The showIntrovert() function in Figure 9-13 could call the showPerson() function, which is public in DemoBasePerson and private in Introvert, and the showPerson() function could then access salary

9

Page 24: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• A main() program that instantiates an Introvert object cannot access any of the four data items directly; all four fields are private to the Introvert class

9

Page 25: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

9

Page 26: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• To summarize the use of three class access specifiers with class data members:

– If a class has private data members, they can be used only by member functions of that class

– If a class has protected data members, they can be used by member functions of that class and by member functions of derived classes

– If a class has public data members, they can be used by member functions of that class, by member functions of derived classes, and by any other functions’ including the main() function of a program

9

Page 27: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Choosing the Class Access Specifier

• With one generation of inheritance, there are nine possible combinations, as shown in Table 9-1

• Remember the following:

– Private data can be accessed only by a class’s member functions (or friend functions), and not by any functions in derived classes

– If a class serves as a base class, most often its data members are protected, and its member functions are public

– The access spcifier in derived classes is most often public, so that the derived class can refer to all nonprivate data and functions of the base class

– When a class is derived from another derived class, the newly derived class never has any more liberal access to a base class member than does its immediate predecessor

9

Page 28: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Summary of Child Class Member Access Rules

9

Page 29: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• When a new class is derived from an existing class, the derived class has access to nonprivate member functions in the base class

• The new class also can have its own member functions

• Those functions can have names that are identical to the function names in the base class

• Any child class function with the same name and argument list as the parent overrides the parent function; any child class function with the same name as the parent, yet with an argument that differs from the parent’s, overloads the parent function

9

Page 30: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

9

Page 31: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• The Employee setFields() function receives values for fields that are defined in the parent Person class, as well as for fields defined within the Employee class

• Employee::setFields() could directly assign values to idNum, lastName, and firstName, as shown in Figure 9-18

• The highlighted lines of code in Figure 9-18 are identical to lines of code in the parent class version of setFields(), so you can rewrite the Employee class setFields() function to call Person’s setFields() function

9

Page 32: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

9

Page 33: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• In the highlighted statement in the setFields() function in Figure 9-19, the values for num, last, and first are passed to the parent class function, where they are assigned to the appropriate fields

• It is important to use the parent class name (Person) and the scope resolution operator

9

Page 34: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• The output in Figure 9-21 shows that even though you set fields for a Person and an Employee by using separate functions that require separate argument lists, you use the same outputData() function that exists within the parent class for both a Person and an Employee

9

Page 35: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

9

Page 36: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• A derived class object can be assigned to a base class object, as in aPerson = worker;

• The assignment causes each data member to be copied from worker to aPerson, and leaves off any data for which the base class doesn’t have members

• The reverse assignment cannot take place without writing a specialized function

• When any class member function is called, the steps shown on page 333 of the textbook take place

9

Page 37: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding and Overloading Parent Class Functions

• In the set of steps outlined on pages 333 and 334 of the textbook, you create a RaceCar class as a child of the Car class you created earlier

• A RaceCar has all the attributes of a Car, but its maximum allowed speed is higher

• Overriding a base class member function with a derived member function demonstrates the concept of polymorphism

9

Page 38: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Constructor Initialization Lists

• Many classes use a constructor function to provide initial values for fields when a class object is created; that is, many functions simply contain a series of assignment statements

• As an alternative to the separate prototype and implementation of the constructor shown in Figure 9-25, you can implement the constructor within the declaration section for the class as an inline function

9

Page 39: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The Item Class

9

Page 40: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Constructor Initialization Lists

• As another alternative, you can replace the assignment statements within a constructor body for Item with a constructor initialization list

• A constructor initialization list provides values for class fields in the same statement that contains the constructor definition

9

Page 41: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Constructor Initialization Lists

• The constructor initialization list shown in

Figure 9-27 initializes itemNum with the value

of n and itemPrice with the value of p

9

Page 42: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding the Difference Between Assignment

and Initialization

• The difference between assignment and initialization is often very subtle, and programmers sometimes mingle the two terms rather casually

• When you declare a simple scalar variable and give it a value, you can declare and assign in two separate statements, for example:int z;

z = 100;

• Alternatively, you can initialize a variable, declaring it and assigning it a value within a single statement, for example:int z = 100;

OR

int z(100);

9

Page 43: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Understanding the Difference Between Assignment

and Initialization

• There are at least four reasons to understand the use of constructor initialization lists:– Many C++ programmers prefer this method, so it is used

in many programs– Technically, a constructor should initialize rather than

assign values– Reference variables and constant class members

cannot be assigned values; they must be initialized– When you create a derived class and instantiate an

object, a parent class object must be constructed first. You add a constructor initialization list to a derived class constructor to construct the parent class.

9

Page 44: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Providing for Base Class Construction

• When you instantiate an object in a C++ program, you automatically call its constructor function

• This pattern holds true whether you write a custom constructor or use a default constructor

• When you instantiate a derived class object, a constructor for its base class is called first, followed by the derived class constructor

• This format is followed even if the base and derived classes both have only default constructors

9

Page 45: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Providing for Base Class Construction

9

Page 46: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Providing for Base Class Construction

• If PetStoreAnimal were a simple base class, the PetStoreAnimal class constructor would require just an integer argument that would be assigned to the petAge field

• However, because PetStoreAnimal is derived from PetStoreItem, a PetStoreAnimal object is constructed, and the PetStoreItem class constructor also will be called

• The prototype for the PetStoreAnimal class constructor must provide values for all the arguments it needs as well as all the arguments its parent needs

9

Page 47: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The PetStoreAnimal Class

9

Page 48: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Providing for Base Class Construction

• Figure 9-31 shows one more option for coding the PetStoreAnimal class

• In this example, the constructor initialization list initializes both PetStoreItem and petAge

9

Page 49: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding Inherited Access

• Nine inheritance access specifier combinations are possible: base class members that are private, protected, or public can be inherited with private, protected, or public access

• In addition, you can override the class access specifier for any specific class members

9

Page 50: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The DemoBasePerson Class

9

Page 51: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding Inherited Access

• If a derived class, SomewhatShy, uses the protected access specifier when inheriting from DemoBasePerson, then the following statements hold true:

– The field named salary, which is private in DemoBasePerson, is inaccessible in the derived class

– The field named age, which is protected in the base class, remains protected in the derived class

– The field named initial, which is public in the base class, becomes protected in the derived class

– The function setPerson() and showPerson(), which are public in DemoBasePerson, become protected in the derived class

9

Page 52: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding Inherited Access

• For the showPerson() function to become public within SomewhatShy, the highlighted statement in Figure 9-33 must appear in the public section of the SomewhatShy class

• Additionally, the DemoBasePerson class name and scope resolution operator must appear before the showPerson() function name

• Finally, and most oddly, no parentheses appear after the showPerson() function name within the child class

9

Page 53: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Overriding Inherited Access

• However, you can override the inherited access to make an individual member’s access more conservative

• For most C++ classes, data is private or protected, and most functions are public

9

Page 54: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Multiple Inheritance

• A child class also can derive from more than one base class; this type of inheritance is called multiple inheritance

9

Page 55: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The Employee Class

9

Page 56: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Multiple Inheritance

• The new Patent class, shown in Figure 9-37, inherits from both Product and Employee

• The Patent class includes all members of each of its parents’ classes

• Figure 9-38 shows a main() function that uses a Patent object, and Figure 9-39 shows the output

• Five arguments are passed to the Patent class setData() function

9

Page 57: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

The Patent Class

9

Page 58: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Multiple Inheritance9

Page 59: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Multiple Inheritance

• In the steps on pages 345 to 348 of the textbook, you create two classes

• The Investment class holds data about Investment objects, such as initial value and profit figures

• The House class holds data about House objects, such as number of bedrooms and square footage

9

Page 60: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Disadvantages of Using Multiple Inheritance

• Multiple inheritance is never required to solve a programming problem; the same results always can be achieved through single inheritance

• You already have encountered one problem with multiple inheritance: if two parent classes contain members with the same name, then the awkward syntax of using the scope resolution operator is required when using those members

• In the set of steps referred to on pages 349 and 350 of the textbook, you alter the House and Investment classes you created earlier so they each contain a constructor that requires arguments

9

Page 61: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Virtual Base Classes

• You already know that a base class may have many descendants through single inheritance

• A college might use a Person base class, for example, and create child classes Student, Employee, and Alumnus

• You also know that a class may inherit from two other classes through multiple inheritance

9

Page 62: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Using Virtual Base Classes

• The class definition for StudentEmployee would begin as follows:

class StudentEmployee: public Student, public Employee

• The word virtual indicates that the base class should be used only once

• The headers of the classes become:

class Student : virtual public Person

AND

class Employee : virtual public Person

9

Page 63: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Summary

• Inheritance allows you to create classes that derive most of their attributes from existing classes

• Programs in which you create classes that are derived from existing classes offer several advantages: you save time because much of the code needed for your class is already written and tested

• To create a derived class, you include the keyword class, the derived class name, a colon, a class access specifier, and the base class name in the class header; as with other classes, definition statements within a pair of curly braces follow

9

Page 64: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Summary

• When a class serves as a base class to others, all of its members can be used within the child class functions, except for any private members

• When you define a derived class, you can insert one of the three class access specifiers (public, private, or protected) just prior to the base class name

• You can override parent class functions within a child class

• As an alternative to separate prototypes and implementation of a constructor, you can use a constructor initialization list

9

Page 65: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Summary

• When you declare a variable without an initial value, it holds garbage until you make an assignment

• If a base class does not contain a default constructor, then you must provide a constructor for use by the derived class

• You can override the class access specifier when it does not suit your needs for some of the members of the class

9

Page 66: Understanding Inheritance Object-Oriented Programming Using C++ Second Edition 9

Summary

• Using multiple inheritance, a child class can derive from more than one base class

• Multiple inheritance poses special problems, and some programmers are opposed to its use

• When a base class is parent to two or more classes that in turn are co-parents to another generation, you risk duplicate inheritance

• To remedy this situation, you use the keyword virtual when you define each of the child classes; this indicates that the base class should be used only once

9