Top Banner
CMSC 202 Inheritance
49

CMSC 202

Jan 01, 2016

Download

Documents

avram-lang

CMSC 202. Inheritance. “is-a”. A car is a vehicle A sorted list is a list A pump is a piece of equipment A student is a person A professor is a faculty member A lecturer is a faculty member. More “is-a”. Many objects have an “is-a” relationship with another object. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: CMSC 202

CMSC 202

Inheritance

Page 2: CMSC 202

2

“is-a”

• A car is a vehicle

• A sorted list is a list

• A pump is a piece of equipment

• A student is a person

• A professor is a faculty member

• A lecturer is a faculty member

Page 3: CMSC 202

3

More “is-a”

• Many objects have an “is-a” relationship with another object.

• One object is more a more specialized version of another

• This “is-a” relationship is represented in OOP by inheritance.

Page 4: CMSC 202

4

UMBCCOMMUNITY

MEMBER

STUDENT FACULTY MEMBER

GRADUATESTUDENT

UNDERGRADSTUDENT

PROFESSOR LECTURER

An inheritance hierarchy

Page 5: CMSC 202

5

Inheritance Hierarchy

• In an inheritance hierarchy, objects at the top levels are more general in nature than the ones on the lower levels.

• The lower you go in the hierarchy, the more specialized the objects become

• Inheritance is transitive across levels– A “graduate student” is a “student” – A “student” is a “UMBC community member”– Therefore a “graduate student” is also a “UMBC

community member”

Page 6: CMSC 202

6

Inheritance and Classes

• The more general object is a referred to as a “base class”.

• The more specialized object is a “derived class”.• The base class contains all that’s common among

the derived classes.• The attributes (data) and behavior (methods) of

the base class are inherited (shared) by the derived class.

• The derived class extends or modifies the base class behavior.

Page 7: CMSC 202

7

Inheritance, Generalizationand Specialization

• Inheritance is the mechanism for sharing attributes and operations among classes

• Generalization and Specialization are two viewpoints of the is-a relationship.

• The base class can be considered a generalization of of the derived class

• More commonly, the derived class is considered a specialization of the base class

Page 8: CMSC 202

8

“is-a” vs. “has-a” vs. “uses-a”

• Inheritance is the mechanism for implementing the “is-a” relationship between objects.

• Composition/Aggregation is the mechanism for implementing the “has-a” relationship between objects (like Stack and List in project 4).

• An object uses another object by calling a public method of that object.

Page 9: CMSC 202

9

Inheritance and OOP

• Inheritance is an abstraction for sharing similarities among classes while preserving their differences

• Inheritance allows us to group classes into families of related types, allowing for the sharing of common operations and data

• Inheritance of operations promotes code reuse

Page 10: CMSC 202

10

Inheritance in C++

• C++ provides three methods for inheritance– “public” inheritance is used to implement the

“is-a” relationship– “private” inheritance is use to implement the

“is-implemented-in-terms-of” relationship– No one knows what “protected” inheritance is

• Our discussions are limited to PUBLIC inheritance

Page 11: CMSC 202

11

Public inheritance means “is-a”If you write that class D (“Derived”) publicly inherits

from class B (“Base”), then you are telling C++ compilers (and human readers of your code) that every D is a B, but not vice-versa. You are saying that B represents a more general concept than D, that D represents a more specialized concept than B. You are asserting that anywhere an object of type B can be used, an object of type D can be used just as well, because every object of type D is an object of type B. On the other hand, if you need an object of type D, and object of type B will not do; every D is a B, but not vice-versa.

-- “Effective C++ Second Edition”, page 155

Page 12: CMSC 202

12

Make sure inheritance models “is-a”

Is a square a rectangle?Absolutely. We all know that a square is a rectangle whose length and width are the same.

Should we model a square by publicly inheriting from rectangle?A good discussion we’ll have.

Page 13: CMSC 202

13

“is-a” vs. “has-a” revisited

The textbook uses an example in which a Circle class inherits from a Point class.

What do you think of this?

Page 14: CMSC 202

14

A Simple Class Example

// a military time classclass Time { public: Time(int h = 0, int m = 0, int s = 0);

void setTime (int h, int m, int s); void increment( );void printTime ( ) const;

private: int hrs; // 0 - 23

int mins;int secs;

};

Page 15: CMSC 202

15

Some Time Methods

Time::Time (int initHrs, int initMins, int initSecs) : hrs (initHrs), mins (initMins), secs (initSecs){

// no code – uses member initialization list}

void Time::setTime (int hours, int minutes, int seconds){

hrs = hours;mins = minutes;secs = seconds;

}

Page 16: CMSC 202

16

Time::Increment

void Time::increment ( ){ secs++; if (secs > 59) {

secs = 0;mins++;if (mins > 59) { mins = 0; hrs++; if (hrs > 23)

hrs = 0; } }}

Page 17: CMSC 202

17

Time::PrintTime

// print time as hh:mm:ss with leading zeroesvoid Time::printTime ( ) const{ if (hrs < 10)

cout << '0'; cout << hrs << ':'; if (mins < 10)

cout << '0'; cout << mins << ':'; if (secs < 10)

cout << '0'; cout << secs;}

Page 18: CMSC 202

18

An extended time class// ExtTime publicly inherits (is derived from) Timeclass ExtTime: public Time { public:

enum ZoneType = {EST, CST, MST, PST, EDT, CDT, MDT, PDT};

ExtTime(int h = 0, int m = 0, int s = 0, ZoneType z = EST);

void setExtTime (int h, int m, int s, ZoneType z);void printExtTime( ) const;

private:ZoneType zone;

};

Page 19: CMSC 202

19

What does this mean?• ExtTime publicly inherits from Time.• Time is the base class.• ExtTime is the derived class.• All of Time’s public methods are

available to the ExtTime class and to users of the ExtTime class

• ExtTime extends Time by adding the time zone; an example of specialization

• ExtTime DOES NOT have access to Time’s private members

Page 20: CMSC 202

20

An Aside -- Protected Access

// A base class can give a derived class direct access to // some members by placing them in the protected section// only derived classes (and their friends) can access // protected membersclass Time { public:

Time(int h = 0, int m = 0, int s = 0);void setTime(int h, int m, int s); void increment( );void printTime( ) const;

protected: // potential ENCAPSULATION VIOLATION!int hrs, mins, secs;

};

Page 21: CMSC 202

21

ExtTime constructor

// the ExtTime constructor calls the Time (base class) // constructor using the member initialization list// Without this, Time’s default constructor would be called// Base class constructors are called first// ExtTime then initializes its own data member

ExtTime::ExtTime (int Hrs, int Mins, int Secs, ZoneType Zone)

: Time (Hrs, Mins, Secs){

zone = Zone;}

Page 22: CMSC 202

22

ExtTime::setExtTime// SetExtTime calls Time::SetTime to set // (private) hours, mins and secs inherited from Time

void ExtTime::setExtTime(int h, int m, int s, ZoneType z)

{

SetTime (h, m, s);

zone = z;

}

Page 23: CMSC 202

23

ExtTime::printExtTime

void ExtTime::printExtTime ( ) const{ static char* zoneString[8] = {

“EST", "CST", "MST", "PST", "EDT", "CDT", "MDT", "PDT"

}; printTime ( ); // a base class method cout << ' ' << zoneString[zone];}

Page 24: CMSC 202

24

Using ExtTimemain ( ) { ExtTime eTime (12, 0, 0); // noon, EST

eTime.printExtTime ( ); // ExtTime method eTime.increment ( ); // an inherited method eTime.printTime ( ); // just prints hh:mm:ss eTime.setExtTime (13, 12, 7, ExtTime::PST); eTime.printExtTime ( ); // ExtTime method

}

Page 25: CMSC 202

25

Assignment operator

• The base class assignment operator (operator=) is not inherited and NOT called automatically from the derived class assignment operator

Page 26: CMSC 202

26

Time::operator=

Time& Time::operator= (const Time& rhs){

if (this != &rhs){

hrs = rhs.hrs;mins = rhs.mins;secs = rhs.secs;

} return *this;}

Page 27: CMSC 202

27

Erroneous ExtTime::operator=

ExtTime& ExtTime::

operator=(const ExtTime &rhs)

{if (this != &rhs)

zone = rhs.zone;

return *this;

}

Page 28: CMSC 202

28

What happens?

ExtTime eTime1 (12, 30, 0, ExtTime::EST);

ExtTime eTime2 (13, 45, 30, ExtTime::PDT);

// assignment only changes the zone

eTime2 = eTime1;

// eTime2 is 13:45:30 EST

Page 29: CMSC 202

29

Correct ExtTime::operator=ExtTime& ExtTime::

operator=(const ExtTime &rhs){

if (this != &rhs){

// explicitly call base class op=Time::operator= (rhs);zone = rhs.zone;

}return *this;

}

Page 30: CMSC 202

30

Other Notes on Inheritance• Base class constructors and destructors are NOT inherited

• The base class constructor (destructor) will automatically be invoked when the derived class is constructed (destroyed)

• The base class constructor will be called first

• The derived class destructor will be called first (objects are destroyed in the reverse order they are constructed)

• Base class operator= is NOT inherited and NOT automatically called by derived class operator=

• “friendship” is NOT inherited. I.e. a friend of the base class is not automatically a friend of the derived class

Page 31: CMSC 202

31

Inheritance vs. Templates

• A stack must be homogeneous because it only holds objects of one kind a time. So if we want several kinds of stacks, we need several kinds of classes.

• Now consider a problem that deals with cats. Each breed of cat is slightly different, from the others so you’ll need separate classes.

• These problems sound similar, yet result in different software designs

“Effective C++, Second Edition”, item 41

Page 32: CMSC 202

32

Stacks and Cats

• The difference is in the relationship the behavior and the type of object being manipulated.

• We have many types of both stacks and cats.• As we’ve seen the behavior of a stack is NOT

affected by the type of object stored in it and was implemented as a template.

• Different cats, on the other hand, behave differently depending on what type of cat they are. So you can’t just write one class to handle every kind of cat – template won’t work.. We need inheritance

Page 33: CMSC 202

33

Inheritance vs. Templatessummary

• A template should be used to generate a collection of classes when the type of object does not affect the behavior of the class’s functions

• Inheritance should be for a collection of classes when the type of object does affect the behavior of the class’s functions.

Page 34: CMSC 202

34

Specialization by overriding functions

• An inheritance hierarchy shows how more specialized classes are derived from more general classes.

• One primary mechanism of this specialization is overriding functions (methods)

• Overriding a method in the derived class means defining a method with the exact same signature as a method in the base class. The derived class method “hides” the base class method from the user

Page 35: CMSC 202

35

Overriding is NOT overloading

• Recall that overloading a function meant using the same function name, but with different parameters.

• Overriding a function means redefining a function using the same name and parameters. This is possible only with inheritance.

Page 36: CMSC 202

36

Going back in Time

In our Time/ExtTime example, ExtTime extended time by adding new methods and data members. But suppose ExtTime was defined a little differently.

Suppose instead of having printExtTime( ), the ExtTime class redefined printTime( ).

Page 37: CMSC 202

37

// ExtTime overrides Time’s printTime( ) methodclass ExtTime: public Time { public: enum ZoneType = {EST, CST, MST, PST,

EDT, CDT, MDT, PDT}; ExtTime(int h = 0, int m = 0, int s = 0,

ZoneType z = EST); void setExtTime (int h, int m, int s, ZoneType z); void printTime( ) const; // function OVERRIDING private: ZoneType zone; };

Revise ExtTime class with function overriding

Page 38: CMSC 202

38

ExtTime::printTime( )

void ExtTime::printTime ( ) const

{// new code for printing hours, mins, secs

// or call Time::printTime( )

// then output the zone

}

Page 39: CMSC 202

39

// main can’t call Time::printTime( ) because it’s// lexically “hidden” behind ExtTime::printTime( )

main ( ) { ExtTime eTime (12, 0, 0); // noon, EST

eTime.increment ( ); // an inherited method eTime.printTime ( ); // overridden method

}

Page 40: CMSC 202

40

Interface vs.. Implementation

• A function’s interface is just its prototype (declaration)

• A function’s implementation is the code inside the function (the definition)

Page 41: CMSC 202

41

Inheriting only the interface

• Sometimes you want derived classes to inherit only the interface of a member function.

• C++ provides this capability with “pure virtual” functions in the base class

virtual void draw ( ) const = 0;

Page 42: CMSC 202

42

Inheriting the interface and the ability to override the

implementation• Sometimes you want derived classes to inherit

both the interface and the implementation, but allow them to override the default implementation the base class provides

• C++ provides this capability with (impure?) virtual functions in the base class

virtual void error (const string & msg);

Page 43: CMSC 202

43

Inheriting the interface and an unchangeable implementation

• Sometimes you derived classes to inherit both the interface and the implementation without allowing them to override anything.

• C++ provides this with nonvirtual functions in the base class

int objectID ( ) const;

Page 44: CMSC 202

A Shape exampleclass Shape { // a base classpublic: virtual void draw( ) const = 0; // pure virtual function virtual void error (const string& msg); // virtual function int objectID ( ) const; // nonvirtual function . . . . . . };

// some derived classes

class Rectangle : public Shape { . . . . . };

class Ellipse : public Shape { . . . . . };

See “Effective C++ Second Edition”, Item 36

Page 45: CMSC 202

45

draw( ) • draw( ) is a pure virtual function. It’s presence

means that Shape is an “abstract” class and cannot be instantiated.

• The purpose of a pure virtual function is to have derived classes inherit the interface only

• It’s reasonable for all shapes to be drawable, but the Shape class can provide no reasonable default implementation.

• We are saying to designers of derived classes –“You must provide a draw function, but I have no idea how you’re going to implement it.”

Page 46: CMSC 202

46

error ( )

• Error( ) is a virtual function.• Virtual functions provides an interface and a

default implementation which the derived class is at liberty to override.

• Shape::error( ) says that every Shape must support a function named error() and each derived class is free to handle the error in anyway it sees fit. If the derived class doesn’t want to do anything special, it can fall back on the default behavior provided by the Shape class.

Page 47: CMSC 202

47

objectID ( )

• objectID( ) is a nonvirtual function.• Nonvirtual functions are provided in the base class

so that derived classes inherit a function’s interface as well as a mandatory implementation

• A nonvirtual function provides an invariant over specialization because it specifies behavior that is not supposed to change.

Page 48: CMSC 202

48

Two important points about interfaces and implementation

• Interfaces are always inherited. Since public inheritance means “is-a” anything that is true of the base class is also true of it’s derived classes, so if a function applies to the class, it must also apply to its subclasses.

• Never override a nonvirtual function. Theoretically, nonvirtual functions provide a mandatory implementation so should not be redefined. Pragmatically, you’re code won’t always work the way you want. (more on this later).

Page 49: CMSC 202

49

More notes on interface/implementation

• Any class that defines one or more (pure) virtual function should define a virtual destructor (more later)

• It’s sometimes useful to declare a class containing nothing but pure virtual functions. Such a class is called a “protocol class” and provides only function interfaces for derived classes.