Tải bản đầy đủ (.pdf) (10 trang)

A Complete Guide to Programming in C++ part 53 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (234.71 KB, 10 trang )

499
Inheritance
This chapter describes how derived classes can be constructed from
existing classes by inheritance. Besides defining derived classes, we will
also discuss
■ how members are redefined
■ how objects are constructed and destroyed, and
■ how access control to base classes can be realized.
chapter
23
500

CHAPTER 23 INHERITANCE

CONCEPT OF INHERITANCE
Is relation
Car
Properties
and capacities
of class
Car
Properties
and capacities
of class
Car
Properties
and capacities
of class
Car
Additional
properties and


capacities of class
PassCar
Additional
properties and
capacities of class
Truck
PassCar Truck
CONCEPT OF INHERITANCE

501
ᮀ Base Classes and Derived Classes
Inheritance allows new classes to be constructed on the basis of existing classes. The new
derived class “inherits” the data and methods of the so-called base class. But you can add
more characteristics and functionality to the new class.
A fleet management program used by a car hire company needs to handle all kinds of
vehicles—automobiles, motorcycles, trucks, and so on. All of these vehicles have an
identification number that indicates the vehicle, the manufacturer, and the vehicle sta-
tus, such as “hired,” “repair shop,” and so on. Additionally, operations such as “modify
status” are required for the class.
To differentiate between vehicle types, various classes are derived from the base class
Car, such as PassCar, which is used to represent passenger-carrying vehicles. This class
has additional attributes, such as the number of seats, type, sunroof (yes/no), and various
additional operations.
ᮀ Is Relationship
An object of the PassCar type is a special object of the Car class. A passenger vehicle
is a special kind of car. In cases like this we can say that the derived class establishes an is
relationship to the base class.
We distinguish between this close relationship and a so-called has relationship. As
already mentioned, a has relationship occurs between two classes when an member of
one class has another class type. An Account object has a string object to represent

the name of the account holder, for example.
ᮀ Data Abstraction and Reusability
Inheritance has a number of important benefits for software developers:
■ data abstraction: General characteristics and abilities can be handled by generic
(base) classes and specializations can be organized in hierarchical relationships by
means of derived classes. This makes it easier to manage complex situations and
relationships.
■ re-usability: Classes that you have defined and tested can be reused and adapted to
perform new tasks. The base class implementation need not be known for this
purpose: only the public interfaces are required.
502

CHAPTER 23 INHERITANCE
B
Base class B
C
D
B is a direct
base class
B is an indirect
base class
class C : public B
{
private:
// Declaration of additional private
// data members and member functions
public:
// Declaration of additional public
// data members and member functions
};


DERIVED CLASSES
Defining a derived class
Direct and indirect derivation
DERIVED CLASSES

503
When you define a derived class, the base class, the additional data members and meth-
ods, and the access control to the base class are defined.
The opposite page shows a schematic definition of a derived class, C. The C class
inherits the B class, which is defined in the public section following the colon. The
private and public sections contain additional members of the C class.
ᮀ Access to Public Members in the Base Class
Access privileges to the base class B are designated by the public keyword that pre-
cedes the B. In other words,
■ all the public members in base class B are publicly available in the derived class
C.
This kind of inheritance ports the public interface of the base class to the derived
class where it is extended by additional declarations. Thus, objects of the derived class
can call the public methods of the base class. A public base class, therefore, imple-
ments the is relationship; this is quite common.
There are some less common cases where access to the members of the base class
needs to be restricted or prohibited. Only the methods of class C can still access the
public members of B, but not the users of that class. You can use private or pro-
tected
derivation to achieve this (these techniques will be discussed later).
ᮀ Access to Private Members of the Base Class
The private members of the base class are protected in all cases. That is,
■ the methods of the derived class cannot access the private members of the base
class.

Imagine the consequences if this were not so: you would be able to hack access to the
base class by simply defining a derived class, thus undermining any protection offered by
data encapsulation.
ᮀ Direct and Indirect Base Classes
The derived class C can itself be a base class for a further class, D. This allows for class
hierarchies. Class B then becomes an indirect base class for class D.
In the graphic on the opposite page, the arrow ↑ means directly derived from. That is,
class D is a direct derivation of class C and an indirect derivation of B.
504

CHAPTER 23 INHERITANCE
// car.h: Definition of baseclass Car and
// of the derived class PassCar
//
#include <iostream>
#include <string>
using namespace std;
class Car // Base class
{
private:
long nr;
string producer;
public: // Constructor:
Car( long n = 0L, const string& prod = "");
// Access methods:
long getNr(void) const { return nr; }
void setNr( long n ) { nr = n; }
const string& getProd() const{ return producer; }
void setProd(const string& p){ producer = p; }
void display( void ) const; // Display a car

};
class PassCar : public Car // Derived class
{
private:
string passCarType;
bool sunRoof;
public: // Constructor:
PassCar( const string& tp, bool sd,
int n = 0 , const string& h = "");
// Access methods:
const string& getType() const{ return passCarType; }
void setType( const string s) { passCarType = s; }
bool getSunRoof() const { return sunRoof; }
void setSunRoof( bool b ) { sunRoof = b; }
void display() const;
};

MEMBERS OF DERIVED CLASSES
Base class Car and derived class PassCar
MEMBERS OF DERIVED CLASSES

505
Let’s look at the example on the opposite page to illustrate how derived classes are
defined. The Car class and a derived class PassCar are defined in the example.
ᮀ Data Members and Methods
The base class Car contains two data members, nr and producer, which are used to
represent an identification number and the name of the manufacturer. The derived class
PassCar inherits these data members. Thus, an object of the PassCar class also con-
tains the data members nr and producer. The object includes a so-called base sub-
object of type Car.

The PassCar class additionally contains the data members passCarType and
sunRoof to represent a passenger vehicle with or without a sunroof. So a PassCar type
object has a total of four data members. For the sake of simplicity, we have omitted fur-
ther data members, such as the number of seats, etc.
The base class Car contains a constructor, access methods, and the method
display(), which is used for screen output. The methods are also inherited by the
derived class PassCar.
In the PassCar class a constructor, additional access methods, and a second output
function also called display() are declared. The derived class thus inherits a method
called display() and declares a method with the same name. The display()
method is said to have been redefined.
Every member function and every data member in a derived class can be redefined.
The member assumes a new meaning for the derived class. The member inherited from
the base class is also available in the derived class and will retain its original meaning.
We will be looking at this point in more detail later.
ᮀ Public Interface
Since the Car class is a public base class of the PassCar class, all the public mem-
bers of the base class are available in the derived class. For example, you can call the
getNr() method for an object named cabrio in the PassCar class.
Example: cout << "Car number: "<< cabrio.getNr();
The public interface of the derived class thus comprises
■ the public members of the base class and
■ the public members additionally defined in the derived class.
506

CHAPTER 23 INHERITANCE
class Car
class PassCar : public Car
void PassCar::display( void) const
private:

private:
public:
public:
<< getNr();
<< getProd();
cout << "Type: "<< passCarType;
cout << "Type: "<< passCarTyp
if( sunRoof) cout << "yes";
else cout << " no";
cout << endl;
cout << "\nCar number: "
string passCarType;
long nr;
string producer;
long getNr(void);
bool sunRoof;
cout << "\nProducer: "
}
{
{
{
}
}
. . .
. . .
. . .
ok
ok
not ok


MEMBER ACCESS
Accessing members of base class Car
MEMBER ACCESS

507
ᮀ Access to Additional Members
The methods of derived classes can access any member additionally defined in the
derived class.
Example: const string& getType() const
{ return passCarType; }
The getType() method directly accesses the private data member passCarType in
the PassCar class in this example.
ᮀ Access to Private Members of the Base Class
However, a private member of the base class is not directly accessible for the methods of
the derived class. The output function display() in the derived class PassCar, for
example, cannot contain the following statement:
Example: cout << "Producer: " << producer;
As producer is a private data member of the base class Car, the compiler would issue
an error message at this point.
Methods belonging to derived classes only have indirect access to the private data
members of the base class. They use access methods in the public declaration of the
base class for this purpose. The opposite page shows a version of the display() method
that calls the get methods in its base class Car.
When you call an access method, you do not need to state the method’s base class.
The base class is identified by the this pointer, which is passed implicitly as an argu-
ment. The call to getProd() on the opposite page is thus equivalent to:
Example: this->getProd();
ᮀ Name Lookup
The following rules apply when searching for the name of a method:
■ the compiler looks for the name of the method called in the derived class first

■ if the name cannot be found, the compiler walks one step up the tree and looks
for a public method with that name.
The above example thus calls the getProd() in the base class Car, as the method is
not defined in the PassCar class.
508

CHAPTER 23 INHERITANCE
// Within file Car.cpp
// This version of method PassCar::display() calls
// the method display() of the base class.
//
void PassCar::display( void) const
{
Car::display(); // Method in base class
cout << "Type: " << passCarType;
cout << "\nSunroof: ";
if(sunRoof)
cout << "yes "<< endl;
else
cout << "no " << endl;
}

REDEFINING MEMBERS
New version of method display()

×