object-oriented programming: polymorphism zhen jiang west chester university [email protected]

43
Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University [email protected]

Upload: ethelbert-parsons

Post on 31-Dec-2015

238 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Object-Oriented Programming: Polymorphism

Zhen JiangWest Chester University

[email protected]

Page 2: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Outline 10.1 Introduction 10.2 Relationships Among Objects in an Inheritance

Hierarchy 10.2.1 Invoking Base-Class Functions from Derived-Class Objects 10.2.2 Aiming Derived-Class Pointers at Base-Class Objects 10.2.3 Derived-Class Member-Function Calls via Base-Class

Pointers 10.2.4 Virtual Functions 10.3 Type Fields and switch Structures 10.4 Abstract Classes 10.5 Virtual Destructors

Page 3: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.1 IntroductiondataPtr

intPtr*ptr

ptr[i] or *(ptr+i)

ptr-> ptr->or

Ptr int[]

Ptr struct

Page 4: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.1 Introduction

7

5

ptr data1

data2

int main()

{

int data1=7,data2=5,*p;

p=&data1;

cout <<*p;

//remove pointer from i

p=&data2;

cout <<*p;

return 0;

} // end main

By using integerpointer p, we can access any integer.

connection to any integer

operations on that integer

(integer) pointer providesgeneral operation (on integers)

(integer) pointer provides?

Page 5: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.1 Introduction Polymorphism

“In the general” Virtual functions and dynamic binding

Between base class and derived classes Will explain how polymorphism works

Makes programs extensible New classes added easily, can still be processed

Page 6: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2 Relationships Among Objects in an Inheritance Hierarchy

Previously (Section 9.4), Circle inherited from Point Manipulated Point and Circle objects using member functions

Now Invoke functions using base-class/derived-class pointers Introduce virtual functions

Page 7: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2 Relationships Among Objects in an Inheritance Hierarchy

Key concept Derived-class object can be treated as base-class object

“is-a” relationship Base class is not a derived class object

Base class Derived class

Derived

Derived

? ?

Ptr of DerivedPtr of Base Base

obj.fun()

(*ptr).fun()

Ptr->fun()

Page 8: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Aim pointers (base, derived) at objects (base, derived) Base pointer aimed at base object Derived pointer aimed at derived object Base pointer aimed at derived object

“is a” relationship Circle “is a” Point

Will invoke base class functions Problem: function call depends on the class of the

pointer/handle Does not depend on object to which it points With virtual functions, this can be changed (more later)

10.2.1 Invoking Base-Class Functions from Derived-Class Objects

Page 9: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2.1 Invoking Base-Class Functions from Derived-Class Objects

Example 1 Step 1

Csc513_v_p1_0.h

Csc513_v_p1_0.cppCsc513_v1_0.cpp

//csc513_v1_0.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1_0.h"

// Point class definition

using std::cout;

using std::endl;

int main()

{

Point point( 30, 50 );

Point *pointPtr = NULL;

// base-class pointer

return 0;

} // end main

Page 10: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v_p1_0.h

//copyright: zjiang 3/19/2003

#ifndef POINT_H

#define POINT_H

class Point {

public:

Point( int = 0, int = 0 );

// default constructor

private:

int x; // x part of coordinate pair

int y; // y part of coordinate pair

}; // end class Point

#endif

//csc513_v_p1_0.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1_0.h"

using std::cout;

Point::Point( int xValue, int yValue )

: x( xValue ), y( yValue )

{

// empty body

} // end Point constructor

Member initializers specify values of x and y.

Page 11: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Example 1 Step 2 (call member

functions by using pointer)Csc513_v_p1.hCsc513_v_p1.cppCsc513_v1_1.cpp

//csc513_v1_1.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1.h"

// Point class definition

using std::cout;

using std::endl;

int main() {

Point point( 30, 50 );

Point *pointPtr = 0;

// base-class pointer

cout << endl<<"Point: ";

point.print(); // invokes Point's print

cout <<endl;

pointPtr = &point;

pointPtr->print(); // invokes Point's print

cout << endl;

return 0;

} // end main

Call “(*pointPtr).Print();”

Page 12: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v_p1.h

//copyright: zjiang 3/19/2003

#ifndef POINT_H

#define POINT_H

class Point {

public:

Point( int = 0, int = 0 ); // default constructor

int getX() const; // return x from coordinate pair

int getY() const; // return y from coordinate pair

void print() const; // output Point object

private:

int x; // x part of coordinate pair

int y; // y part of coordinate pair

}; // end class Point

#endif

Usually, for each attribute, we need to develop set and get two member functions. Why?

Page 13: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v_p1.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1.h"

using std::cout;

Point::Point( int xValue, int yValue )

: x( xValue ), y( yValue )

{

// empty body

} // end Point constructor

int Point::getX() const

{

return x;

} // end function getX

int Point::getY() const

{

return y;

} // end function getY

// output Point object

void Point::print() const

{

cout << '[' << getX() << ", " << getY() << ']';

} // end function print

Page 14: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Example 1 Step 3

Csc513_v_p1.h

Csc513_v_p1.cppCsc513_v_c1.hCsc513_v_c1.cppCsc513_v1.cpp

Page 15: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v1.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1.h" // Point class definition

#include "csc513_v_c1.h" // Circle class definition

using std::cout;

using std::endl;

int main()

{

Point point( 30, 50 );

Point *pointPtr = 0; // base-class pointer

Circle circle( 120, 89, 2.7 );

Circle *circlePtr = 0; // derived-class pointer

cout << endl<<"Point: ";

point.print(); // invokes Point's print

cout << endl<<"Circle: ";

circle.print();

// invokes Circle's print

pointPtr = &point;

pointPtr->print(); // invokes Point's print

cout << endl;

circlePtr = &circle;

circlePtr->print();

// invokes Circle's print

return 0;

} // end main

Page 16: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

New class Circle?

Page 17: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v_c1.h

//copyright: zjiang 3/19/2003

#ifndef CIRCLE_H

#define CIRCLE_H

#include "csc513_v_p1.h" // Point class definition

class Circle : public Point {

public:

// default constructor

Circle( int = 0, int = 0, double = 0.0 );

double getRadius() const; // return radius

void setRadius( double ); // set radius

void print() const; // Inherit print of point but still

// need output Circle object

private:

double radius; // Circle's radius

}; // end class Circle

#endif

Page 18: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v_c1.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_c1.h"

using std::cout;

using std::endl;

// default constructor

Circle::Circle( int xValue, int yValue,

double radiusValue )

: Point( xValue, yValue )

{ // call base-class constructor

setRadius( radiusValue );

} // end Circle constructor

void Circle::setRadius( double radiusValue )

{

radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );

} // end function setRadius

double Circle::getRadius() const

{

return radius;

} // end function getRadius

void Circle::print() const

{

cout << "center = ";

Point::print(); // invoke Point's print function

cout << "; radius = " << getRadius() <<endl;

} // end function print

Page 19: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Example 1 Step 4 (Base-class pointer)

Csc513_v_p1.h

Csc513_v_p1.cppCsc513_v_c1.hCsc513_v_c1.cppCsc513_v1_3.cpp

Page 20: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v1_3.cpp//copyright: zjiang 3/19/2003#include <iostream>#include "csc513_v_p1.h" // Point class definition#include "csc513_v_c1.h" // Circle class definition

using std::cout;using std::endl;

int main(){Point point( 30, 50 );Point *pointPtr = 0; // base-class pointer

Circle circle( 120, 89, 2.7 );Circle *circlePtr = 0; // derived-class pointer

cout << endl<<"Point: ";point.print(); // invokes Point's printcout << endl<<"Circle: ";circle.print(); // invokes Circle's print

pointPtr = &point; pointPtr->print(); // invokes Point's printcout << endl;

circlePtr = &circle; circlePtr->print(); // invokes Circle's print

pointPtr = &circle; pointPtr->print(); // invokes Point's print

return 0;} // end main

Page 21: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Previous example Aimed base-class pointer at derived object

Circle “is a” Point

Aim a derived-class pointer at a base-class object Compiler error

No “is a” relationship Point is not a Circle Circle has data/functions that Point does not

setRadius (defined in Circle) not defined in Point

10.2.2 Aiming Derived-Class Pointers at Base-Class Objects

Page 22: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

1 // Fig. 10.6: fig10_06.cpp2 // Aiming a derived-class pointer at a base-class object.3 #include "point.h" // Point class definition4 #include "circle.h" // Circle class definition5 6 int main()7 {8 Point point( 30, 50 ); 9 Circle *circlePtr = 0; 10 11 // aim derived-class pointer at base-class object 12 circlePtr = &point; // Error: a Point is not a Circle13 14 return 0;15 16 } // end main

C:\cpphtp4\examples\ch10\fig10_06\Fig10_06.cpp(12) : error C2440: '=' : cannot convert from 'class Point *' to 'class Circle *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Aim a derived-class pointer at a base-class object

Page 23: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Handle (pointer/reference) Base-pointer can aim at derived-object

But can only call base-class functions (see in the following sample)

Calling derived-class functions is a compiler error Functions not defined in base-class

Common theme Data type of pointer/reference determines functions it

can call

10.2.3 Derived-Class Member-Function Calls via Base-Class Pointers

Page 24: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

1 // Fig. 10.7: fig10_07.cpp2 // Attempting to invoke derived-class-only member functions3 // through a base-class pointer.4 #include "point.h" // Point class definition5 #include "circle.h" // Circle class definition6 7 int main()8 {9 Point *pointPtr = 0;10 Circle circle( 120, 89, 2.7 );11 12 // aim base-class pointer at derived-class object13 pointPtr = &circle;14 15 // invoke base-class member functions on derived-class16 // object through base-class pointer17 int x = pointPtr->getX();18 int y = pointPtr->getY();19 pointPtr->setX( 10 );20 pointPtr->setY( 10 );21 pointPtr->print();22

Page 25: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

23 // attempt to invoke derived-class-only member functions24 // on derived-class object through base-class pointer 25 double radius = pointPtr->getRadius(); 26 pointPtr->setRadius( 33.33 ); 27 double diameter = pointPtr->getDiameter(); 28 double circumference = pointPtr->getCircumference(); 29 double area = pointPtr->getArea(); 30 31 return 0;32 33 } // end main

These functions are only defined in Circle. However, pointPtr is of class Point.

Page 26: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(25) : error C2039: 'getRadius' : is not a member of 'Point' C:\cpphtp4\examples\ch10\fig10_07\point.h(6) : see declaration of 'Point' 

C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(26) : error C2039: 'setRadius' : is not a member of 'Point' C:\cpphtp4\examples\ch10\fig10_07\point.h(6) : see declaration of 'Point' 

C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(27) : error C2039: 'getDiameter' : is not a member of 'Point' C:\cpphtp4\examples\ch10\fig10_07\point.h(6) : see declaration of 'Point' 

C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(28) : error C2039: 'getCircumference' : is not a member of 'Point' C:\cpphtp4\examples\ch10\fig10_07\point.h(6) : see declaration of 'Point' 

C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(29) : error C2039: 'getArea' : is not a member of 'Point' C:\cpphtp4\examples\ch10\fig10_07\point.h(6) : see declaration of 'Point'

Page 27: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2.4 Virtual Functions Typically, pointer-class

determines functions virtual functions

Object (not pointer) determines function called

Why useful? Suppose Circle, Triangle,

Rectangle derived from Shape Each has own draw function

To draw any shape Have base class Shape pointer,

call draw Program determines proper

draw function at run time (dynamically)

Treat all shapes generically

Page 28: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2.4 Virtual Functions Declare draw as virtual in base class

Override draw in each derived class Like redefining, but new function must have same signature

If function declared virtual, can be overridden virtual void draw() const; Once declared virtual, virtual in all derived classes

Good practice to explicitly declare virtual, why? Dynamic binding

Choose proper function to call at run time If function called from object, uses that object’s

definition

Page 29: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2.4 Virtual Functions Example 2

Redo Point and Circle example with virtual functions

Base-class pointer to derived-class object Will call derived-class function

Page 30: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

1 // csc513_v_p1.h (Fig. 10.8: point.h)2 // Point class definition represents an x-y coordinate pair.3 #ifndef POINT_H4 #define POINT_H5 6 class Point {7 8 public:9 Point( int = 0, int = 0 ); // default constructor10 11 int getX() const; // return x from coordinate pair12 int getY() const; // return y from coordinate pair13 14 virtual void print() const; // output Point object15 16 private: 17 int x; // x part of coordinate pair18 int y; // y part of coordinate pair19 20 }; // end class Point21 22 #endif

Print declared virtual. It will be virtual in all derived classes.

Page 31: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

1 // csc513_v_p1.h (Fig. 10.8: point.h)

Print declared virtual. It will be virtual in all derived classes.

1 //csc513_v_c1.h ( Fig. 10.9: circle.h)2 // Circle class contains x-y coordinate pair and radius.3 #ifndef CIRCLE_H4 #define CIRCLE_H 5 #include "point.h" // Point class definition6 7 class Circle : public Point {8 9 public:10 // default constructor11 Circle( int = 0, int = 0, double = 0.0 ); 12 13 void setRadius( double ); // set radius14 double getRadius() const; // return radius15 16 virtual void print() const; // output Circle object17 18 private: 19 double radius; // Circle's radius20 21 }; // end class Circle22 23 #endif

Better be virtual.

Page 32: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v1_3.cpp

//copyright: zjiang 3/19/2003

#include <iostream>

#include "csc513_v_p1.h" // Point class definition

#include "csc513_v_c1.h" // Circle class definition

using std::cout;

using std::endl;

int main()

{

Point point( 30, 50 );

Point *pointPtr = 0; // base-class pointer

Circle circle( 120, 89, 2.7 );

Circle *circlePtr = 0; // derived-class pointer

cout << endl<<"Point: ";

point.print(); // invokes Point's print

cout << endl<<"Circle: ";

circle.print();

// invokes Circle's print

pointPtr = &point;

pointPtr->print(); // invokes Point's print

cout << endl;

circlePtr = &circle;

circlePtr->print();

// invokes Circle's print

pointPtr = &circle;

pointPtr->print();

// invokes Point's print

return 0;

} // end main

At run time, the program determines that pointPtr is aiming at a Circle object, and calls Circle’s print function. This is an example of polymorphism.

Page 33: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.2.4 Virtual Functions Polymorphism

Same message, “print”, given to many objects All through a base pointer

Message takes on “many forms” Summary

Base-pointer to base-object, derived-pointer to derived Straightforward

Base-pointer to derived object Can only call base-class functions

Derived-pointer to base-object Compiler error

Page 34: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.3 Type Fields and switch Structures

One way to determine object's class Give base class an attribute

shapeType in class Shape Use switch to call proper print function

Many problems May forget to test for case in switch If add/remove a class, must update switch structures

Time consuming and error prone

Better to use polymorphism Less branching logic, simpler programs, less debugging

Page 35: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Abstract classes Sole purpose: to be a base class (called abstract base

classes) Incomplete

Derived classes fill in "missing pieces" Cannot make objects from abstract class

However, can have pointers and references Concrete classes

Can instantiate objects Implement all functions they define Provide specifics

10.4 Abstract Classes

Page 36: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.4 Abstract Classes

Abstract classes not required, but helpful To make a class abstract

Need one or more "pure" virtual functions Declare function with initializer of 0 virtual void draw() const = 0;

Regular virtual functions Have implementations, overriding is optional

Pure virtual functions No implementation, must be overridden

Abstract classes can have data and concrete functions Required to have one or more pure virtual functions

Page 37: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.4 Abstract Classes

Abstract base class pointers Useful for polymorphism

Application example Abstract class Shape

Defines draw as pure virtual function Circle, Triangle, Rectangle derived from Shape

Each must implement draw Screen manager knows that each object can draw itself

Page 38: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

10.4 Abstract Classes Example 3

Csc513_people.h, csc513_people.cpp Csc513_student.h, csc513_student.cpp Csc513_faculty.h, csc513_faculty.cpp Csc513_v3.cpp

Page 39: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_v3.cpp//copyright zjiang 3/19/2003

#include <iostream>#include "csc513_people.h"#include "csc513_student.h"#include "csc513_faculty.h"

int main(){

Student tony(123456,900123456);Faculty tom(654321,123456789);People * ptr [2];

ptr[0]=&tony;ptr[1]=&tom;for(int i=0;i<2;i++){

ptr[i]->printSSN();ptr[i]->working();

}return 0;

}

Derived classBase class

Faculty

People Student

Page 40: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_student.h//copyright zjiang 3/19/03

#ifndef STUDENT_H#define STUDENT_H#include "csc513_people.h"

class Student:public People{public:Student(long, long);long getSN();virtual void working();private:long sn;};

#endif

//csc513_faculty.h//copyright zjiang 3/19/03

#ifndef FACULTY_H#define FACULTY_H#include "csc513_people.h"

class Faculty:public People{public:Faculty(long, long);long getID();virtual void working();private:long id;};#endif

//csc513_people.h//copyright zjiang 3/19/03#ifndef PEOPLE_H#define PEOPLE_H

class People{public:People(long);void printSSN();virtual void working()=0;private:long ssn;};

#endif

Page 41: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_people.cpp//copyright zjiang 3/19/2003

#include <iostream>#include "csc513_people.h"

using std::cout;

People::People(long n){

ssn=n;}

void People::printSSN(){

cout << "SSN:"<<ssn<<" ";}

Page 42: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

//csc513_student.cpp//copyright zjiang 3/19/2003

#include <iostream>#include "csc513_student.h"

using std::cout;using std::endl;

Student::Student(long n1, long n2):People(n2){

sn=n1;}

long Student::getSN(){

return sn;}

void Student::working() {

long studentid=Student::getSN();cout << "Student#:"<<studentid;cout << " now is studying. "<<endl;

}

//csc513_faculty.cpp//copyright zjiang 3/19/2003

#include <iostream>#include "csc513_faculty.h"

using std::cout;using std::endl;

Faculty::Faculty(long n1, long n2):People(n2){

id=n1;}

long Faculty::getID(){

return id;}

void Faculty::working(){

cout << "Working#:"<<getID();cout << " now is teaching. "<<endl;

}

Page 43: Object-Oriented Programming: Polymorphism Zhen Jiang West Chester University zjiang@wcupa.edu

Base class pointer to derived object If destroyed using delete, behavior unspecified

Simple fix Declare base-class destructor virtual

Makes derived-class destructors virtual Now, when delete used appropriate destructor called

When derived-class object destroyed Derived-class destructor executes first Base-class destructor executes afterwards

Constructors cannot be virtual

10.5 Virtual Destructors