M The University Of Michigan Andrew M. Morgan EECS498-006 Lecture 25 Savitch Ch. 15 Polymorphism.

Slides:



Advertisements
Similar presentations
Object-Oriented Programming Session 9 Course : T Programming Language Concept Year : February 2011.
Advertisements

Interra Induction Training
Chapter 15 Polymorphism and Virtual Functions. Copyright © 2006 Pearson Addison-Wesley. All rights reserved Learning Objectives Virtual Function.
M The University Of Michigan Andrew M. Morgan EECS Lecture 01 Savitch Ch. 2 C++ Basics Flow Of Control.
M The University Of Michigan Andrew M. Morgan EECS Lecture 14 Savitch Ch. 9.0 C++ String Data Type C-Strings.
M The University Of Michigan Andrew M. Morgan EECS Lecture 09 Savitch Ch Compiling With Multiple Files Make Utility.
M The University Of Michigan Andrew M. Morgan EECS Lecture 22 Savitch Ch. 16 Intro To Standard Template Library STL Container Classes STL Iterators.
M The University Of Michigan Andrew M. Morgan Andrew M Morgan1 EECS Lecture 03 Savitch Ch. 3-4, Misc More on Functions Memory, Activation Records,
M The University Of Michigan Andrew M. Morgan EECS Lecture 06 Savitch Ch. 5 Arrays Multi-Dimensional Arrays.
M The University Of Michigan Andrew M. Morgan EECS Lecture 24 Savitch Ch. 14 Inheritance.
Savitch N/A Randomness In Programming Simulations
M The University Of Michigan Andrew M. Morgan Andrew M Morgan1 EECS Lecture 05 Savitch Ch Streams Stream States Input/Output.
M The University Of Michigan Andrew M. Morgan EECS Lecture 18 Savitch Ch. 17 Linked Data Structures.
Copyright © 2002 Pearson Education, Inc. Slide 1.
Chapter 6 Structures and Classes. Copyright © 2006 Pearson Addison-Wesley. All rights reserved. 6-2 Learning Objectives Structures Structure types Structures.
Copyright © 2003 Pearson Education, Inc. Slide 1.
Chapter 17 Linked Lists.
Object Oriented Programming with Java
You can do more than what you think ……… If you believe you can.
Constructors: Access Considerations DerivedClass::DerivedClass( int iR, float fVar) : BaseClass(fVar) { m_uiRating = uiR; } Alternatively DerivedClass::DerivedClass(
CLASS INHERITANCE Class inheritance is about inheriting/deriving properties from another class. When inheriting a class you are inheriting the attributes.
Introduction to Arrays Chapter What is an array? An array is an ordered collection that stores many elements of the same type within one variable.
Copyright © 2012 Pearson Education, Inc. Chapter 15: Inheritance, Polymorphism, and Virtual Functions.
Chapter 13 – Introduction to Classes
Abstract Class, Packages and interface from Chapter 9
Copyright  Hannu Laine C++-programming Part 8 Hannu Laine.
C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for.
1 CSC241: Object Oriented Programming Lecture No 21.
Review of Inheritance. 2 Several Levels of Inheritance Base Class B Derived class D Derived class D1.
SUMMARY: abstract classes and interfaces 1 Make a class abstract so instances of it cannot be created. Make a method abstract so it must be overridden.
EC-241 Object-Oriented Programming
Inheritance Math 130 B Smith: Consider using the example in SAMS Teach Yourself C++ in 24 hours B Smith: Consider using the example in SAMS Teach Yourself.
K. Stirewalt CSE 335: Software Design Foundations: Language Mechanisms and Primitive OO Concepts Lecture 2: Polymorphism Topics: – Polymorphism and virtual.
1 Inheritance Inheritance is a natural way to model the world in object-oriented programming. It is used when you have two types of objects where one is.
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
Virtual Functions Junaed Sattar November 10, 2008 Lecture 10.
Engineering H192 - Computer Programming The Ohio State University Gateway Engineering Education Coalition Lect 28P. 1Winter Quarter Inheritance and Overloading.
CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging.
Copyright 2008 by Pearson Education Building Java Programs Chapter 9 Lecture 9-4: Interfaces reading: self-check: exercises: #11.
Learners Support Publications Pointers, Virtual Functions and Polymorphism.
Overview of Previous Lesson(s) Over View  OOP  A class is a data type that you define to suit customized application requirements.  A class can be.
CONSTRUCTORS AND THEIR TYPES. Prepared by. MURLI MANOHAR. PGT (COMP
Chapter 10 Inheritance and Polymorphism
Computer Programming & Applications Mohamed Iqbal Pallipurath Lecture 02P. 1 Inheritance and Overloading Lecture 28.
CSE 143 Lecture 20 Abstract classes. 2 Circle public class Circle { private double radius; public Circle(double radius) { this.radius = radius; } public.
Inheritance CSI 1101 Nour El Kadri. OOP  We have seen that object-oriented programming (OOP) helps organizing and maintaining large software systems.
نظام المحاضرات الالكترونينظام المحاضرات الالكتروني Object Oriented Programming(Objects& Class) Classes are an expanded concept of data structures: like.
C# - Inheritance Ashima Wadhwa. Inheritance One of the most important concepts in object- oriented programming is inheritance. Inheritance allows us to.
1 Inheritance Inheritance is a natural way to model the world in object-oriented programming. It is used when you have two types of objects where one is.
Classes Sujana Jyothi C++ Workshop Day 2. A class in C++ is an encapsulation of data members and functions that manipulate the data. A class is a mechanism.
CSC241 Object-Oriented Programming (OOP) Lecture No. 17.
Structure A Data structure is a collection of variable which can be same or different types. You can refer to a structure as a single variable, and to.
1 C++ Classes & Object Oriented Programming Overview & Terminology.
CSCI-383 Object-Oriented Programming & Design Lecture 17.
CSC 143 O 1 CSC 143 Inheritance and Object Oriented Design.
1 Section 11.4 Java Interfaces – The Implementation Perspective Fundamentals of Java: AP Computer Science Essentials, 4th Edition Lambert / Osborne.
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.
Modern Programming Tools And Techniques-I
CSC241: Object Oriented Programming
Review: Two Programming Paradigms
C# - Inheritance and Polymorphism
Inheritance and Overloading
HYBRID INHERITANCE : AMBIGUITY REMOVAL
Inheritance Virtual Functions, Dynamic Binding, and Polymorphism
Inheritance: Polymorphism and Virtual Functions
Inheritance: Polymorphism and Virtual Functions
Inheritance Virtual Functions, Dynamic Binding, and Polymorphism
Inheritance: Polymorphism and Virtual Functions
Computer Science II for Majors
INTERFACES Explained By: Sarbjit Kaur. Lecturer, Department of Computer Application, PGG.C.G., Sector: 42, Chandigarh.
Presentation transcript:

M The University Of Michigan Andrew M. Morgan EECS Lecture 25 Savitch Ch. 15 Polymorphism

M M EECS498 EECS498 Andrew M Morgan2 Inheritance Revisited Recall that inheritance allows one class to obtain attributes and functionality from another class Base classes should be generic-type classes which contain members common to all objects Many new classes can inherit from the base class A set of classes which all inherit from the same base class are related in that sense This relationship can be advantageous in C++

M M EECS498 EECS498 Andrew M Morgan3 Inheritance and Use Note the interfaces for the derived classes class square:public shape { public: square(int inX, int inY, int size); float area(); float circumf(); }; class rectangle:public shape { public: rectangle(int inX, int inY, int l, int w); float area(); float circumf(); }; class circle:public shape { public: circle(int inX, int inY, int r); float area(); float circumf(); }; class rightTriangle:public shape { public: rightTriangle(int inX, int inY, int l, int w); float area(); float circumf(); }; class shape { public: shape(int inX, int inY); };

M M EECS498 EECS498 Andrew M Morgan4 Inheritance Use cot'd Can we use inheritance to our advantage here? Put area() and circumf() in the shape class? –This would not work, since the implementations of these functions are different for different shape types –You would have to shadow shape's area() in every single derived class –Therefore, there is no point in putting it in shape, if each derived will have its own function with unique functionality class shape { public: shape(int inX, int inY); float area();//??? Good idea??? float circumf();//??? Good idea??? };

M M EECS498 EECS498 Andrew M Morgan5 Discussion of Sample Program Now we will consider a program dealing with shapes and areas, etc... class ShapeClass { public: ShapeClass(int inX, int inY):xPos(inX),yPos(inY) { } private: int xPos; int yPos; shape():xPos(0),yPos(0) { } };

M M EECS498 EECS498 Andrew M Morgan6 class SquareClass:public ShapeClass { public: SquareClass(int inX, int inY, int size):ShapeClass(inX,inY),len(size) { } float area() { float res; cout << "In square::area" << endl; res = (float)(len * len); return (res); } float circumf() { float res; res = (float)(4 * len); return (res); } private: int len; SquareClass():ShapeClass(0,0),len(1) { } }; Program Without Polymorphism, p. 1

M M EECS498 EECS498 Andrew M Morgan7 class RectangleClass:public ShapeClass { public: RectangleClass(int inX, int inY, int l, int w):ShapeClass(inX,inY), len(l),wid(w) { } float area() { float res; cout << "In rectangle::area" << endl; res = (float)(len * wid); return (res); } float circumf() { float res; res = (float)(2 * len + 2 * wid); return (res); } private: int len; int wid; RectangleClass():ShapeClass(0,0),len(1),wid(1) { } }; Program Without Polymorphism, p. 2

M M EECS498 EECS498 Andrew M Morgan8 class CircleClass:public ShapeClass { public: CircleClass(int inX, int inY, int r):ShapeClass(inX,inY),rad(r) { } float area() { float res; cout << "In circle::area" << endl; res = M_PI * rad * rad; return (res); } float circumf() { float res; res = M_PI * 2 * rad; return (res); } private: int rad; CircleClass():ShapeClass(0,0),rad(1) { } }; Program Without Polymorphism, p. 3

M M EECS498 EECS498 Andrew M Morgan9 class RightTriangleClass:public ShapeClass { public: RightTriangleClass(int inX, int inY, int l, int w):ShapeClass(inX,inY), len(l),wid(w) { } float area() { float res; cout << "In rightTriangle::area" << endl; res = 0.5 * len * wid; return (res); } float circumf() { float res; res = len + wid + sqrt(len*len + wid*wid); return (res); } private: int len; int wid; RightTriangleClass():ShapeClass(0,0),len(1),wid(1) { } }; Program Without Polymorphism, p. 4

M M EECS498 EECS498 Andrew M Morgan10 float addAreas(int numCircs, CircleClass **circs, int numSquares, SquareClass **squares, int numRects, RectangleClass **rects, int numTris, RightTriangleClass **tris) { int i; float res = 0.0; for (i = 0; i < numCircs; i++) { res += circs[i]->area(); } for (i = 0; i < numSquares; i++) { res += squares[i]->area(); } for (i = 0; i < numRects; i++) { res += rects[i]->area(); } for (i = 0; i < numTris; i++) { res += tris[i]->area(); } return (res); } Program Without Polymorphism, p. 5

M M EECS498 EECS498 Andrew M Morgan11 float addCircumfs(int numCircs, CircleClass **circs, int numSquares, SquareClass **squares, int numRects, RectangleClass **rects, int numTris, RightTriangleClass **tris) { int i; float res = 0.0; for (i = 0; i < numCircs; i++) { res += circs[i]->circumf(); } for (i = 0; i < numSquares; i++) { res += squares[i]->circumf(); } for (i = 0; i < numRects; i++) { res += rects[i]->circumf(); } for (i = 0; i < numTris; i++) { res += tris[i]->circumf(); } return (res); } Program Without Polymorphism, p. 6

M M EECS498 EECS498 Andrew M Morgan12 int main(void) { float res; int i; int numCircs = 3, numSquares = 1; int numRects = 2, numTris = 4; //Declare arrays of pointers CircleClass **circs = new CircleClass*[numCircs]; SquareClass **squares = new SquareClass*[numSquares]; RectangleClass **rects = new RectangleClass*[numRects]; RightTriangleClass **tris = new RightTriangleClass*[numTris]; int c = 0, s = 0, r = 0, t = 0; circs[c++] = new CircleClass(0, 0, 2); rects[r++] = new RectangleClass(0, 0, 2, 2); rects[r++] = new RectangleClass(4, 6, 8, 8); tris[t++] = new RightTriangleClass(0, 0, 2, 2); squares[s++] = new SquareClass(3, 12, 6); tris[t++] = new RightTriangleClass(10, 10, 6, 8); circs[c++] = new CircleClass(-10, -10, 4); tris[t++] = new RightTriangleClass(0, 22, 4, 5); circs[c++] = new CircleClass(8, 3, 4); tris[t++] = new RightTriangleClass(20, 8, 3, 7); continued on next page Notice the order in which the shapes are allocated... Program Without Polymorphism, p. 7

M M EECS498 EECS498 Andrew M Morgan13 res = addAreas(numCircs, circs, numSquares, squares, numRects, rects, numTris, tris); cout << "Total Areas: " << res << endl; res = addCircumfs(numCircs, circs, numSquares, squares, numRects, rects, numTris, tris); cout << "Total Circumfs: " << res << endl; return(0); } In circle::area In square::area In rectangle::area In rightTriangle::area Total Areas: Total Circumfs: Notice the order in which the shapes were allocated is lost when calling area()... Program Without Polymorphism, p. 8

M M EECS498 EECS498 Andrew M Morgan14 Inheritance Use cot'd But aren't we supposed to group common attribute and functionality together in a base class? –Yes! C++ has a way of dealing with this In most situations, assigning from one type to another is a bad thing. For example: Even assigning one pointer type to another is bad: ShapeClass s; int i; i = s; //Bad news... int *iptr = new int; float *fptr = iptr; //Bad news...

M M EECS498 EECS498 Andrew M Morgan15 Derived Ptr Assigned to Base Ptr However, there is one case where assigning different types is ok You are allowed to assign a pointer to a derived class to a variable declared as a pointer to the base class –This means you can do: Logically, think of it this way: –A circle is a shape - it is just a specialized shape –Therefore, if I am pointing to a shape, I might be pointing to a circle, or a square, or... ShapeClass *sPtr; CircleClass *cPtr = new CircleClass(5,5,1); RectangleClass *rPtr = new RectangleClass(1,1,4,4); sPtr = cPtr; //NOT bad news... sPtr = rPtr; //NOT bad news...

M M EECS498 EECS498 Andrew M Morgan16 But Why? Obvious question: Why would I want to set a shape pointer to a circle pointer? –To allow polymorphism! –In the sample program discussed, we declared 4 separate arrays (square, circle, rectangle, triangle) Consider the code: The above will not compile –It is looking for a member function of the shape class, called area(), but one does not exist ShapeClass *sPtr; CircleClass *cPtr = new CircleClass(5,5,1); sPtr = cPtr; //NOT bad news... sPtr->area(); //Bad news...

M M EECS498 EECS498 Andrew M Morgan17 Again - Then Why? If we can't do this, then why bother with the assignment "sPtr = cPtr;"? –We're not done just yet - we CAN do this, with the correct syntax The base class must be aware that a function called area() exists The derived classes should have an implementation for the function area() (for this example) The base class must be aware that the area() function is special, in that derived classes may have overridden it ShapeClass *sPtr; CircleClass *cPtr = new CircleClass(5,5,1); sPtr = cPtr; //NOT bad news... sPtr->area(); //Bad news...

M M EECS498 EECS498 Andrew M Morgan18 The Keyword virtual The keyword "virtual" is used in C++ for this purpose –Functions can be declared as virtual in a class definition –Virtual functions are special member functions –When a pointer-to-an-object calls a virtual function: First - the type of the object being pointed to is determined - either actually a pointer to an object of this class, or a pointer to an object of a derived class Second - that type is checked to see if it has an implementation to the function –If so, the implementation from the derived class is used –If not, the implementation from the base class is used A virtual function does not need to be overridden, if you don't want different functionality from what is provided in the base class

M M EECS498 EECS498 Andrew M Morgan19 Simple Example class W { public: virtual void print() { cout << "W's print!" << endl; } }; class X:public W { public: void print() { cout << "X's print!" << endl; } }; class Y:public W { public: void notprint() { cout << "Y's func!" << endl; } }; class Z:public W { public: void print() { cout << "Z's print!" << endl; } }; W *Wptr; W Wobj; X Xobj; Y Yobj; Z Zobj; Wobj.print(); Xobj.print(); Yobj.print(); Zobj.print(); cout << endl Wptr = &Wobj; Wptr->print(); Wptr = &Xobj; Wptr->print(); Wptr = &Yobj; Wptr->print(); Wptr = &Zobj; Wptr->print(); W's print! X's print! W's print! Z's print! W's print! X's print! W's print! Z's print! From main:

M M EECS498 EECS498 Andrew M Morgan20 New Discussion of Sample Program class ShapeClass { public: ShapeClass(int inX, int inY):xPos(inX),yPos(inY) { } virtual float area() { cout << "No area for this shape!" << endl; return (0.0); } virtual float circumf() { cout << "No circumf for this shape!" << endl; return (0.0); } private: int xPos; int yPos; ShapeClass():xPos(0),yPos(0) { } };

M M EECS498 EECS498 Andrew M Morgan21 New Derived Shape Classes There are no changes made to the square, rightTriangle, circle, etc classes. The derived shape classes remain exactly as they were in the previous example Keyword virtual only needs to show up in the base class

M M EECS498 EECS498 Andrew M Morgan22 New addAreas and addCircumfs Functions float addAreas(int numShapes, ShapeClass **shapes) { int i; float res = 0.0; for (i = 0; i < numShapes; i++) { res += shapes[i]->area(); } return (res); } float addCircumfs(int numShapes, ShapeClass **shapes) { int i; float res = 0.0; for (i = 0; i < numShapes; i++) { res += shapes[i]->circumf(); } return (res); } Rather than pass in an array and count for each type, just pass in one array of shapes (since all types are shapes via the "is-a" relationship inheritance provides). If adding a new shape type, these functions need not change in ANY way.

M M EECS498 EECS498 Andrew M Morgan23 New main() Using Polymorphism int main(void) { float res; int i, numShapes, ctr = 0; int numCircs = 3, numSquares = 1; int numRects = 2, numTris = 4; numShapes = numCircs + numSquares + numRects + numTris; //Declare arrays of pointers ShapeClass **shapes = new ShapeClass*[numShapes]; shapes[ctr++] = new CircleClass(0, 0, 2); shapes[ctr++] = new RectangleClass(0, 0, 2, 2); shapes[ctr++] = new RectangleClass(4, 6, 8, 8); shapes[ctr++] = new RightTriangleClass(0, 0, 2, 2); shapes[ctr++] = new SquareClass(3, 12, 6); shapes[ctr++] = new RightTriangleClass(10, 10, 6, 8); shapes[ctr++] = new CircleClass(-10, -10, 4); shapes[ctr++] = new RightTriangleClass(0, 22, 4, 5); shapes[ctr++] = new CircleClass(8, 3, 4); shapes[ctr++] = new RightTriangleClass(20, 8, 3, 7); res = addAreas(numShapes, shapes); cout << "Total Areas: " << res << endl; res = addCircumfs(numShapes, shapes); cout << "Total Circumfs: " << res << endl; return(0); } Rather than 4 separate arrays of specific types, I just declare 1 array of type shape*. Since base class pointers can be assigned derived class pointers, just store all object pointers in the shape array.

M M EECS498 EECS498 Andrew M Morgan24 New Version Output In circle::area In rectangle::area In rightTriangle::area In square::area In rightTriangle::area In circle::area In rightTriangle::area In circle::area In rightTriangle::area Total Areas: Total Circumfs: Note: This time, the order in which the shapes were allocated is maintained. Often this is important. The final results (areas and circumferences) are exactly the same.

M M EECS498 EECS498 Andrew M Morgan25 Reminder of Polymorphism The C++ construct of virtual functions allows one common interface for many implementations Virtual functions allow you to use the relationship between classes that derive from the same base class While each derived class may function differently, a common interface can exist Virtual functions have a body –It is executed when either: 1. An object of the class type which defined the virtual function calls it 2. A derived object pointer calls the function, but that object's class did not provide an implementation

M M EECS498 EECS498 Andrew M Morgan26 More About Virtual Functions Consider this example, from a secretary's inventory control program: class SupplyClass { public: virtual void order() { cout << "No order() defined!\n"; } void takeFromCabinet(int num) { if (quantity >= num) quantity -= num; } protected: char *name; //name of supply int quantity; //# in cabinet now }; class PencilClass:public SupplyClass { public: void order() { cout << "Call and " << "ask for Sandy\n"; } private: float leadSize; }; class InkPenClass:public SupplyClass { private: int inkColor; };

M M EECS498 EECS498 Andrew M Morgan27 The Problem... So what is the problem with the previous program? –Some programmer who was in a hurry to meet a deadline forgot to override the order() function for the inkPen class So? It will call the order() that is defined in Supply right? –Yes, but that may not be acceptable. –In this situation, the base class definition of order() does not give any useful information of how to order the supply –Since your company might be an office inventory-control software company, this piece of software could be crucial to the survival of the company, and delivering bad programs could be a big problem for your job security How can I avoid this problem? –Make the function pure virtual !!

M M EECS498 EECS498 Andrew M Morgan28 Pure Virtual Functions A function that is declared pure virtual MUST be overridden in any class that derives from it –This is actually checked at compile time, so you ensure that any programmer that derives a new class from your base class will override it, or else it will not compile A function that is a pure virtual function need not (and can not) have a body defined But what if an object of the base class type tries to call that member function? –This can not happen! –When a class contains one or more pure virtual functions, it becomes an "abstract class" –C++ does not allow you to create objects from an abstract class –Abstract classes serve ONLY as base classes from which to inherit

M M EECS498 EECS498 Andrew M Morgan29 Syntax for Pure Virtual Functions Making the virtual function NULL results in a pure virtual function –Functions in C/C++ are pointers to the memory that holds the executable code for that function –Set that pointer to NULL, which means there is no executable code for this function, making it pure virtual class SupplyClass { public: virtual void order(int num) = 0; void takeFromCabinet(int num) { if (quantity >= num) quantity -= num; } protected: char *name; //name of supply int quantity; //# in cabinet now }; class InkPenClass:public SupplyClass { private: int inkColor; }; This will no longer compile, since the programmer forgot to override the pure virtual function called order()