Polymorphism CMSC 202, Version 4/02.

Slides:



Advertisements
Similar presentations
Copyright © 2012 Pearson Education, Inc. Chapter 15: Inheritance, Polymorphism, and Virtual Functions.
Advertisements

OOP Spring 2007 – Recitation 71 Object Oriented Programming Spring 2006 Recitation 8.
OOP Etgar 2008 – Recitation 71 Object Oriented Programming Etgar 2008 Recitation 7.
Inheritance, Polymorphism, and Virtual Functions
12/08/08MET CS Fall Polymorphism 10. Polymorphism Goal: Goal: Create methods that can be invoked with all object types, base as well as.
Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
Shallow Versus Deep Copy and Pointers Shallow copy: when two or more pointers of the same types point to the same memory – They point to the same data.
Lecture 6: Polymorphism - The fourth pillar of OOP - 1.
1 Data Structures - CSCI 102 CS102 C++ Polymorphism Prof Tejada.
1 Virtual Functions and Polymorphism Chapter What You Will Learn What is polymorphism? How to declare and use virtual functions for abstract classes.
Inheritance in C++ CS-1030 Dr. Mark L. Hornick.
Learners Support Publications Pointers, Virtual Functions and Polymorphism.
1 Classes- Inheritance Multiple Inheritance It is possible to derive a new class from more than one base class. This is called Multiple Inheritance. Under.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Taken from slides of Starting Out with C++ Early Objects Seventh Edition.
Dr. Ahmad R. Hadaegh A.R. Hadaegh California State University San Marcos (CSUSM) Page 1 Virtual Functions Polymorphism Abstract base classes.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Slide
CMSC 202 Inheritance.
TCP1201 OOPDS Lecture 4 1. Learning Objectives  To understand upcasting & downcasting  To understand static polymorphism and dynamic polymorphism 
CMSC 2021 Polymorphism. CMSC 2022 Static vs. Dynamic Binding Binding The determination of which method in the class hierarchy is to be used for a particular.
Copyright 2006 Oxford Consulting, Ltd1 February Polymorphism Polymorphism Polymorphism is a major strength of an object centered paradigm Same.
What Is Inheritance? Provides a way to create a new class from an existing class New class can replace or extend functionality of existing class Can be.
Copyright © 2012 Pearson Education, Inc. Chapter 15: Inheritance, Polymorphism, and Virtual Functions.
1 Lecture 6: Polymorphism - The fourth pillar of OOP -
CMSC 202 Lesson 18 Polymorphism 1. Warmup What errors are present in the following hierarchy? Assume GetCurrentTime() and RingBell() are defined elsewhere.
Chapter -6 Polymorphism
Overview of C++ Polymorphism
CMSC 202 Polymorphism. 10/20102 Topics Binding (early and late) Upcasting and downcasting Extensibility The final modifier with  methods  classes.
Recap Introduction to Inheritance Inheritance in C++ IS-A Relationship Polymorphism in Inheritance Classes in Inheritance Visibility Rules Constructor.
Object Oriented Programming in C++ Chapter 7 Dynamic Binding.
Polymorphism and Virtual Functions One name many shapes behaviour Unit - 07.
CSC241 Object-Oriented Programming (OOP) Lecture No. 17.
Inheritance - 3. Virtual Functions Functions defined as virtual are ones that the base expects its derived classes may redefine. Functions defined as.
CSCI-383 Object-Oriented Programming & Design Lecture 17.
CPSC 252Inheritance II Page 1 Inheritance & Pointers Consider the following client code: const int MAXCLOCKS = 2; Clock* clockPtr[ MAXCLOCKS ]; clockPtr[0]
CSC 143 O 1 CSC 143 Inheritance and Object Oriented Design.
Abstract classes only used as base class from which other classes can be inherit cannot be used to instantiate any objects are incomplete Classes that.
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
Virtual Function and Polymorphism
CMSC 202 Polymorphism.
Advanced Programming in Java
Inheritance CMSC 202, Version 4/02.
CS 3370 – C++ Object-oriented Programming
Class A { public : Int x; A()
Object-Oriented Programming & Design Lecture 18 Martin van Bommel
Object-Oriented Programming
Inheritance, Polymorphism, and Virtual Functions
Polymorphism.
Polymorphism & Virtual Functions
Inheritance, Polymorphism, and Virtual Functions
CMSC 202 Polymorphism.
Inheritance Virtual Functions, Dynamic Binding, and Polymorphism
Polymorphism 1 CMSC 202.
Programming II Polymorphism A.AlOsaimi.
9: POLYMORPHISM Programming Technique II (SCSJ1023) Jumail Bin Taliba
CISC/CMPE320 - Prof. McLeod
Pointers Dr. Bhargavi Goswami Department of Computer Science
Polymorphism Professor Hugh C. Lauer CS-2303, System Programming Concepts (Slides include materials from The C Programming Language, 2nd edition, by Kernighan.
Virtual Functions Polymorphism is supported by C++ both at compile time and at run time. Compile-time polymorphism is achieved by overloading functions.
Jeff West - Quiz Section 12
Inheritance: Polymorphism and Virtual Functions
Inheritance Virtual Functions, Dynamic Binding, and Polymorphism
Today’s Objectives 10-Jul-2006 Announcements Quiz #3
Overview of C++ Polymorphism
VIRTUAL FUNCTIONS RITIKA SHARMA.
Inheritance: Polymorphism and Virtual Functions
C++ Polymorphism Reference and pointer implicit type casting
Advanced Programming in Java
Lecture 6: Polymorphism
Static Binding Static binding chooses the function in the class of the base class pointer, ignoring any versions in the class of the object actually.
Computer Science II for Majors
Presentation transcript:

Polymorphism CMSC 202, Version 4/02

Inheritance and Polymorphism Inheritance allows us to define a family of classes that have common data and behaviors. Polymorphism is the ability to manipulate objects of these classes in a type-independent way. In C++, polymorphism is supported only when we use pointers (or references) to objects. The particular method to invoke on an object is not determined until run-time and is based on the specific type of object actually addressed. CMSC 202, Version 4/02

Review: Inheritance and Pointers A base class pointer can point to an object of a derived class type. The derived class object “is-a” base class object. But we can’t use the pointer to call methods only defined in the derived class. A derived class pointer cannot point to an object of a base class type. The base class doesn’t have any of the extensions provided by the derived class. CMSC 202, Version 4/02

Static vs. Dynamic Binding The determination of which method in the class hierarchy is to be invoked for a particular object. Static (Early) Binding occurs at compile time When the compiler can determine which method in the class hierarchy to use for a particular object. Dynamic (Late) Binding occurs at run time When the determination of which method in the class hierarchy to use for a particular object occurs during program execution. CMSC 202, Version 4/02

Static Binding Time t1, *tPtr = &t1; ExtTime et1, *etPtr = &et1; t1.setTime(12, 30, 00); // static binding et1.setExtTime(13, 45, 30); // static binding t1.printTime( ); // static binding – Time’s printTime( ) et1.printTime( ); // static binding – ExtTime’s printTime( ) tPtr->printTime( ); // static binding - Time’s printTime( ) etPtr->printTime( ); // static binding - ExtTime’s printTime( ) CMSC 202, Version 4/02

Dynamic Binding When the compiler cannot determine the binding of an object to any method. Dynamic binding is determined at runtime. To indicate that a method is to be bound dynamically, the class must use the reserved word virtual in the method’s prototype. When a method is defined as virtual, all overriding methods from that point on down the hierarchy are virtual, even if not explicitly defined to be so. For clarity, explicitly use the virtual reserved word. CMSC 202, Version 4/02

A Common Example - Shapes Circle Rectangle Triangle . . . Operations: - Draw the shape - Indicate an error has occurred - Identify the object CMSC 202, Version 4/02

class Shape { public: virtual void draw ( ) const = 0; // pure virtual virtual void error ( ) const; // virtual void objectID ( ) const; // non-virtual }; void Shape::error ( ) const { cerr << “Shape error” << endl; } void Shape::objectID ( ) const { cout << “A shape” << endl; } CMSC 202, Version 4/02

draw( ) draw( ) is a pure virtual method. A class with one or more pure virtual methods cannot be instantiated. A class that cannot be instantiated is called an abstract class. A class that can is called a concrete class. Only the interface (not the implementation) of a pure virtual function is inherited by derived classes. Derived classes are expected to have their own implementations for the virtual method. CMSC 202, Version 4/02

error( ) error( ) is a virtual (not pure virtual) function. Virtual functions provide both an interface and an implementation to derived classes. The derived classes may override the inherited implementation if they wish. If the implementation is not overridden, the default behavior of the base class will be used. CMSC 202, Version 4/02

objectID( ) objectID( ) is a non-virtual function. Nonvirtual functions are provided in a base class so that derived classes inherit a function’s interface as well as a “mandatory” implementation. A non-virtual function specifies behavior that is not supposed to change. That is, it is not supposed to be overridden. (Technically, it can be.) CMSC 202, Version 4/02

}; void Circle::draw ( ) const class Circle : public Shape { public: virtual void draw( ) const; // method for drawing a circle virtual void error ( ) const; // overriding Shape::error( ) }; void Circle::draw ( ) const { // code for drawing a circle } void Circle::error ( ) const { cout << “Circle error” << endl; } CMSC 202, Version 4/02

}; void Rectangle::draw ( ) const class Rectangle : public Shape { public: virtual void draw( ) const; // method for drawing a rectangle virtual void error ( ) const; // overriding Shape::error( ) }; void Rectangle::draw ( ) const { // code for drawing a rectangle } void Rectangle::error ( ) const { cout << “Rectangle error” << endl; } CMSC 202, Version 4/02

Dynamic Binding (con’t) Now, consider these pointers: Shape *pShape; Circle *pCircle = new Circle; Rectangle *pRectangle = new Rectangle; Each pointer has static type based on the way it is declared. A pointer’s dynamic type is determined by the type of object to which it currently refers. CMSC 202, Version 4/02

Dynamic Binding (con’t) pShape = pCircle; // pShape’s dynamic type is now // Circle pShape->draw( ); // calls Circle::draw and draws a // circle pShape = pRectangle; // pShape’s dynamic type is // now Rectangle pShape->draw ( ); // calls Rectangle::draw and // draws a rectangle CMSC 202, Version 4/02

Pure Virtual Functions and Abstract Classes Would we ever really want to draw an object of type Shape? Would we ever really want to even instantiate an object of type Shape? Shape is really just a “place holder” in the class hierarchy. Therefore, Shape should be an abstract class. And draw( ) should be pure virtual. CMSC 202, Version 4/02

An Array of Base Class Pointers Shape *shapes[3]; shapes[0] = new Circle; shapes[1] = new Rectangle; shapes[2] = new Triangle; for (int s = 0; s < 3; s++) shapes[s]->draw( ); CMSC 202, Version 4/02

A Simple Animal Hierarchy Dog Cat Whale CMSC 202, Version 4/02

private: string name; int nrLegs; }; class Animal { public: Animal ( ) {name = “no name”, nrLegs = 0;} Animal ( string s, int L) : name (s), nrLegs(L) { } virtual ~Animal ( ) { } // virtual destructor virtual void speak ( ) const { cout << “Hi, Bob”; } string getName ( ) const { return name; } int getNrLegs ( ) const { return nrLegs;} void setName (string s) { name = s; } void setNrLegs (int legs) { nrLegs = legs;} private: string name; int nrLegs; }; CMSC 202, Version 4/02

class Dog: public Animal { public: Dog( ): Animal("dog", 4), breed("dog") { } Dog(string s1, string s1): Animal(s1, 4), breed(s2) { } virtual ~Dog( ) { } virtual void speak( ) const {cout << "Bow Wow";} void setBreed(string s1) {breed = s1;} string getBreed( ) const {return breed;} void speak(int n) const // overloading speak( ) {for (int j=0; j<n; j++) speak(); } private: string breed; }; CMSC 202, Version 4/02

class Whale : public Animal { public: Whale ( ) { } Whale(string n) : Animal(n, 0) { } virtual ~Whale ( ) { } private: }; CMSC 202, Version 4/02

int main ( ) { Animal anAnimal (“Homer”, 2); Dog aDog (“Fido”, “mixed”); Whale aWhale (“Orka”); anAnimal.speak( ); // Animal’s speak( ) aDog.speak( ); // Dog’s speak( ) -- overriding aDog.speak( 4 ); // Dog’s speak( ) -- overloading aWhale.speak( ) ; // Animal’s speak( ) -- inherited Animal *zoo[ 3 ]; zoo[0] = new Animal; zoo[1] = new Dog (“Max”, “Terrier”); zoo[2] = new Whale; for (int a = 0; a < 3; a++) { cout << zoo[a]->getName( ) << “ says: “; zoo[a] -> speak( ); // dynamic binding -- polymorphism } return 0; } CMSC 202, Version 4/02

Polymorphism and Non-Member Functions An important use of polymorphism is the writing of non-member functions to deal with all classes in an inheritance hierarchy. This is accomplished by defining the function parameters as pointers (or references) to base class objects, then having the caller pass in a pointer (or reference) to a derived class object. Dynamic binding calls the appropriate method. These functions are often referred to as polymorphic functions. CMSC 202, Version 4/02

drawShape( ) With a Pointer void drawShape (Shape *sp) { cout << “I am “; sp -> objectID ( ); sp -> draw ( ); if (something bad) sp->error ( ); } What is the output if drawShape( ) is passed: - a pointer to a Circle object? - a pointer to a Rectangle object? Circle: “I am a shape”, (objectID is nonvirtual) then the drawing of a circle. if (something bad) then the output is “Circle Error” (error is virtual and overridden in Circle class) Rectangle: “I am a shape”, (objectID is nonvirtual) then the drawing of a Rectangle if (something bad) then the output is “Shape Error” (error is virtual, but NOT overridden in Rectangle) CMSC 202, Version 4/02

drawShape( ) Via Reference void drawShape (Shape& shape) { cout << “I am “ ; shape.objectID ( ); shape.draw ( ); if (something bad) shape.error ( ); } What is the output if drawShape is passed: - a Circle object? - a Rectangle object? Same as with pointers in previous slide CMSC 202, Version 4/02

Don’t Pass by Value A function that has a base class parameter passed by value should only be used with base class objects because: The function isn’t polymorphic. Polymorphism only occurs with parameters passed by pointer or reference. Even though a derived class object can be passed to such a function (a D is-a B), none of the derived class methods or data members can be used in that function. CMSC 202, Version 4/02

Don’t Pass by Value (con’t) void drawShape (Shape shape) // member slicing! { cout << “I am “ ; shape.objectID ( ); shape.draw ( ); if (something bad) shape.error ( ); } What is the output if drawShape is passed: - a Circle object? - a Rectangle object? CMSC 202, Version 4/02

Calling Virtual Methods From Within Other Methods Suppose virtual drawMe( ) is added to Shape and inherited by Rectangle without being overridden. void Shape::drawMe ( void) { cout << “drawing: “ << endl; draw( ); } CMSC 202, Version 4/02

Calling Virtual Methods From Within Other Methods (con’t) Which draw( ) gets called from within drawMe( )? Rectangle r1; r1.drawMe( ); The Rectangle version of draw( ), even though drawMe( ) was only defined in Shape. Why? Because inside of drawMe( ), the call to draw( ) is really this->draw( ); and since a pointer is used, we get the desired polymorphic behavior. CMSC 202, Version 4/02

Polymorphism and Destructors A problem – If an object (with a non-virtual destructor) is explicitly destroyed by applying the delete operator to a base class pointer, the base class destructor is invoked. Shape *sp = new Circle; delete sp; // calls Shape’s destructor // if the destructor is not virtual The Circle object is not “fully” destroyed. So what – C++ standard says that this behavior is undefined Compilers can do whatever they like, but most often the DC destructor is never called CMSC 202, Version 4/02

Polymorphism and Destructors (con’t) Solution -- Declare a virtual destructor for any base class with at least one virtual function. virtual ~Shape ( ); Now, Shape *sp = new Circle; delete sp; will invoke the Circle destructor, which in turn invokes the Shape destructor. CMSC 202, Version 4/02

Designing a Base Class With Inheritance and Polymorphism In Mind For the base class Identify the set of operations common to all the derived classes. Identify which operations are type-independent (these become (pure) virtual to be overridden in derived classes). Identify the access level (public, private, protected) of each operation. For a more complete discussion, see “Essential C++”, Stanley Lippman (section 5.4) CMSC 202, Version 4/02