inheritance copyright kip irvine 2000, all rights reserved

40
Inheritance Inheritance Copyright Kip Irvine 2000, all rights reserved.

Upload: gervase-logan

Post on 17-Jan-2016

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Inheritance Copyright Kip Irvine 2000, all rights reserved

InheritanceInheritance

Copyright Kip Irvine 2000, all rights reserved.

Page 2: Inheritance Copyright Kip Irvine 2000, all rights reserved

Classifying ObjectsClassifying Objects

parent

In their attempts to model the real world, designers classify objects. Inheritance implies a hierarchical relationship.

child

As in biology, the child inherits characteristics from the parent

Page 3: Inheritance Copyright Kip Irvine 2000, all rights reserved

Types of MotorsTypes of Motors

Electric

Clearly, all these classes are related. What might all of these motors have in common?

GasolineDiesel

Solar

Steam

Wind

Page 4: Inheritance Copyright Kip Irvine 2000, all rights reserved

MotorsMotors

Motor class:

Serial numberManufacturerDate of ManufactureModel Numberetc.

The common information can be described in a base class named Motor:

Page 5: Inheritance Copyright Kip Irvine 2000, all rights reserved

Inheritance RelationshipsInheritance Relationships

Motor

ElectricMotor GasolineMotor

The arrows show that the ElectricMotor and GasolineMotor classes are derived from the Motor class.

Page 6: Inheritance Copyright Kip Irvine 2000, all rights reserved

Motor

ElectricMotor GasolineMotor

The Motor class is called the base class, and the other two are called derived classes.

Inheritance Relationships...Inheritance Relationships...

Page 7: Inheritance Copyright Kip Irvine 2000, all rights reserved

Motor

ElectricMotor

Inheritance is often called an is-a relationship. In other words, "an ElectricMotor is a Motor."

Inheritance (Is-A)Inheritance (Is-A)

Page 8: Inheritance Copyright Kip Irvine 2000, all rights reserved

Inheritance Relationships...Inheritance Relationships...

istream

ifstream

Many other classes also have this relationship, such as the istream and ifstream classes.

derives from

Page 9: Inheritance Copyright Kip Irvine 2000, all rights reserved

Example: EmployeesExample: Employees

Employee

Salaried Employee

We could categorize employees based on how they are paid...

Hourly Employee

Commission Employee

Page 10: Inheritance Copyright Kip Irvine 2000, all rights reserved

Types of EmployeesTypes of Employees

Employee

Full-time

...or we might categorize based on their employment status:

Part-time Temporary

Page 11: Inheritance Copyright Kip Irvine 2000, all rights reserved

Inheritance Relationships...Inheritance Relationships...

Vehicle

Dune Buggy MotorCycle

Some relationships are rather remote....

Page 12: Inheritance Copyright Kip Irvine 2000, all rights reserved

Inheritance Relationships...Inheritance Relationships...

PassengerVehicle

SportUtility MiniVan

Others are very specific:

Page 13: Inheritance Copyright Kip Irvine 2000, all rights reserved

PassengerVehicle

Bus Taxicab

Multiple Levels are possible

CargoVehicle

FlatbedTruck ForkLift

CommercialVehicle

Vehicle

Page 14: Inheritance Copyright Kip Irvine 2000, all rights reserved

Other RelationshipsOther Relationships

Tire

Automobile

Here's a relationship that is not based on inheritance. What would you call it?

This is a has-a relationship, also called aggregation.

Page 15: Inheritance Copyright Kip Irvine 2000, all rights reserved

Motor

ElectricMotor

Let's implement two classes that have something in common.

Motor and ElectricMotorMotor and ElectricMotor

Page 16: Inheritance Copyright Kip Irvine 2000, all rights reserved

33333

220.0

Motor

ElectricMotor

33333

An ElectricMotor object contains the same ID number as a Motor, plus the voltage.

Motor and ElectricMotorMotor and ElectricMotor

Page 17: Inheritance Copyright Kip Irvine 2000, all rights reserved

CMotor ClassCMotor Class

class CMotor {public: CMotor() { } CMotor( const string & id );

string get_ID() const;void set_ID(const string & s);

void Display() const;void Input();

private:string m_sID;

}; // more...

The CMotor class definition:

Page 18: Inheritance Copyright Kip Irvine 2000, all rights reserved

CMotor::CMotor( const string & id ){ set_ID(id); }

string CMotor::get_ID() const{ return m_sID; }

void CMotor::set_ID(const string & s){ m_sID = s; }

void CMotor::Display() const{ cout << "[CMotor] ID=" << m_sID; }

void CMotor::Input(){

string temp;cout << "Enter Motor ID: ";cin >> temp;set_ID(temp);

}

Page 19: Inheritance Copyright Kip Irvine 2000, all rights reserved

Creating a Derived ClassCreating a Derived Class

class base {...};

class derived : public base {...};

The base class must appear first. When the derived class is declared, it names the base class.

Any number of classes can be derived from the same base class.

Page 20: Inheritance Copyright Kip Irvine 2000, all rights reserved

CElectricMotor ClassCElectricMotor Class

class CElectricMotor : public CMotor {public: CElectricMotor(); CElectricMotor(const string & id, double volts);

void Display() const;void Input();void set_Voltage(double volts);double get_Voltage() const;

private:double m_nVoltage;

};

Page 21: Inheritance Copyright Kip Irvine 2000, all rights reserved

Base Class InitializerBase Class Initializer

CElectricMotor::CElectricMotor(const string & id, double volts) : CMotor(id){ m_nVoltage = volts;}

A base class initializer calls the constructor in the base class. In this example, the ID number of the motor is passed to the CMotor constructor.

Page 22: Inheritance Copyright Kip Irvine 2000, all rights reserved

Calling Base FunctionsCalling Base Functions

void CElectricMotor::Input(){ CMotor::Input(); // call base class first

double volts;cout << "Voltage: ";cin >> volts;set_Voltage(volts);

}

The Input function exists in both the CMotor and CElectricMotor classes. Rather that duplicate code already written, call the corresponding function in the base class:

Page 23: Inheritance Copyright Kip Irvine 2000, all rights reserved

Calling Base FunctionsCalling Base Functions

void CMotor::Input(){

string temp;cout << "Enter Motor ID: ";cin >> temp;set_ID(temp);

}

This is the Input function in the CMotor class:

Page 24: Inheritance Copyright Kip Irvine 2000, all rights reserved

Display FunctionDisplay Function

void CElectricMotor::Display() const{

// call base class function firstCMotor::Display();

cout << " [CElectricMotor]" << " Voltage=" << m_nVoltage << endl;}

The Display function works the same way. It calls CMotor::Display first.

Page 25: Inheritance Copyright Kip Irvine 2000, all rights reserved

Testing the ClassesTesting the Classes

CMotor mot("33333");mot.Display();cout << endl;

CElectricMotor elec("40000",220.0);elec.Display();cout << endl;

The test program can create instances of both CMotor and CElectricMotor objects.

Page 26: Inheritance Copyright Kip Irvine 2000, all rights reserved

Testing the ClassesTesting the Classes

CElectricMotor elec; // CElectricMotor

elec.set_ID("40000"); // CMotor

elec.set_Voltage(220.0); // CElectricMotor

When using a derived object, functions may be called from both the base class and the derived class.

Page 27: Inheritance Copyright Kip Irvine 2000, all rights reserved

Testing the ClassesTesting the Classes

elec.Input(); // CElectricMotor

elec.Display(); // CElectricMotor

When the same function name exists in both classes, C++ automatically calls the function in the derived class. This is the case with the Input and Display functions:

Page 28: Inheritance Copyright Kip Irvine 2000, all rights reserved

Assigning ObjectsAssigning Objects

CMotor mot;CElectricMotor elec;

mot = elec; // sliced down to a motorelec.get_Voltage(); // okmot.get_Voltage(); // error

You can assign a derived class object to a base class variable. This is called object slicing.

Page 29: Inheritance Copyright Kip Irvine 2000, all rights reserved

Assigning ObjectsAssigning Objects

CMotor mot;CElectricMotor elec;

elec = mot; // error

elec.set_Voltage( 220 ); // ???

But you cannot assign a base class object to a derived variable. That would permit references to nonexistent class members.

Page 30: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected AccessProtected Access

Class members designated as protected are visible to both the current class, as well as all derived classes. (but not to anyone else)

Page 31: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected AccessProtected Access

Here's an example that uses the protected qualifier to limit the visibility of get_ID and set_ID:

class CMotor {public: CMotor() { } CMotor( const string & id );

protected: string get_ID() const;

void set_ID(const string & s);

//...

Page 32: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected AccessProtected Access

The main program cannot call set_ID and get_ID because they are protected:

CMotor M;

M.set_ID("12345"); // error

M.get_ID(); // error

Page 33: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected AccessProtected Access

But functions in CElectricMotor still can access set_ID:

CElectricMotor::CElectricMotor( const string & id, double volts){ m_nVoltage = volts; set_ID(id);}

Page 34: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected InheritanceProtected Inheritance

Let's assume for the moment that CMotor still uses public for all member functions:

class CMotor {public: CMotor() { } CMotor( const string & id );

string get_ID() const;void set_ID(const string & s);

//...

Page 35: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected InheritanceProtected Inheritance

We can use the protected specifier when creating a derived class.

All public functions in the base class become protected in the derived class.

class CElectricMotor : protected CMotor {

//...

};

Page 36: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected InheritanceProtected Inheritance

For example, the main program cannot call set_ID and get_ID on an electric motor because the functions are no longer public:

CElectricMotor EM;

EM.set_ID("12345"); // error

EM.get_ID(); // error

Page 37: Inheritance Copyright Kip Irvine 2000, all rights reserved

Protected InheritanceProtected Inheritance

It might be that the CElectricMotor class author does not want users to know about the motor's ID number.

Functions in CElectricMotor still can access public functions in CMotor. Here is an example:

CElectricMotor::CElectricMotor( const string & id, double volts){ m_nVoltage = volts; set_ID(id);}

Page 38: Inheritance Copyright Kip Irvine 2000, all rights reserved

Private InheritancePrivate Inheritance

Private inheritance causes all functions declared in the base class to be private when a derived class object is created.

At first, there seems to be no difference from protected inheritance: Functions in CElectricMotor can still access member functions in CMotor...

class CElectricMotor : private CMotor {

//...

};

Page 39: Inheritance Copyright Kip Irvine 2000, all rights reserved

Private InheritancePrivate Inheritance

But when we derive a new class (CPumpMotor) from CElectricMotor, the difference shows: CPumpMotor functions cannot access public members of CMotor.

class CPumpMotor : public CElectricMotor {public: void Display() { CMotor::Display(); // not accessible! CElectricMotor::Display(); // this is OK

}

};

Page 40: Inheritance Copyright Kip Irvine 2000, all rights reserved

The EndThe End