Title: Polymorphism
1Polymorphism
2General
- Polymorphism is derived from Greek, and means
having many parts - Polymorphism in OOP can mean
- Overloading functions
- Using class templates
- In a class hierarchy, a single call can be used
to call various methods in derived classes
3- The Classic Example
- A list of Shapes
...
4Conventional Programming 1
- For each Shape in ShapeList
- if(Shape.type is circle) then
- DrawCircle(Shape)
- else if(Shape.type is rectangle) then
- DrawRectangle(Shape)
- else if(Shape.type is point) then
- DrawPoint(Shape)
- else if(Shape.type is line) then
- DrawLine(Shape)
-
5Conventional Programming 2(a little slicker)
- For each Shape in ShapeList
- switch(Shape.type)
- circle
- DrawCircle(Shape)
- rectangle
- DrawRectangle(Shape)
- point
- DrawPoint(Shape)
- line
- DrawLine(Shape)
6Conventional Programming 2(a little slicker)
- For each Shape in ShapeList
- switch(Shape.type)
- circle
- DrawCircle(Shape)
- rectangle
- DrawRectangle(Shape)
- point
- DrawPoint(Shape)
- line
- DrawLine(Shape)
For the SeaLawyers Yep, the 'break' is
missing but since when does 'c' have a 'for each'
statement
7Using Polymorphism
- For each Shape
- Shape.Draw()
8Virtual Methods
- OpStack is-a Stack
- OpStack inherits Stack data/methods
- Additionally, C allows you to assign a pointer
to the OpStack which is of type pointer to Stack
Stack pStack new OpStack Creates a new
OpStack object on the heap and returns a pointer
to an Stack
9Virtual Methods (continued)
- The ability to assign a pointer to the base class
when creating a derived class object is the
enabler for polymorphism - You can now create different types of stacks
(Stack, OpStack, InvertedStack), and give each
one a method called pop - When you call pop at runtime, the correct one
will be called
10Virtual Methods (continued)
- class OpStack public Stack
-
- public
- OpStack()
- OpStack(int maxsize)
- void print()
- void display()
- private
- int nextOp
-
class Stack public Stack() Stack (int
maxsize) void print() virtual void
display() protected int stackArray1024
int TOS
11Virtual Methods (continued)
void Stackprint() cout ltlt Stack print\n
// virtual method void Stackdisplay()
cout ltlt Stack display\n void
OpStackprint() cout ltlt Savings print\n //
overrides the virtual // method void
OpStackdisplay() cout ltlt Savings
display\n
- int main(void)
-
- Stack pStack
- pStack new OpStack
- pStack-gtprint()
- pStack-gtdisplay()
- return 1
-
- Result
- Stack print
- Savings display
12How Virtual Methods Work
- When the derived object OpStack is created
- The Stack constructor is called first
- The OpStack constructor is then called
- These are contiguous in memory
13How Virtual Methods Work (continued)
- The compiler creates a data structure for each
object which has a virtual method - This is called a v-table
- The compiler creates a pointer which points to
the v-table for the object - This is called a v-pointer
14How Virtual Methods Work (continued)
- When Stack is created, the v-table is
initialized to point to the virtual methods in
the Stack class - When the OpStack is created, the v-table is
changed to point to the overriding methods, if
any - This creates some overhead
15Binding
- An executable statement is provided an address to
use to perform its function - Compile time binding (static binding)
- The compiler knows which address to use
- Run time binding (dynamic binding)
- The address to use cannot be reconciled at
compile time, because the information it needs is
generated at run time
16Static and Dynamic Binding
- When a reference to a member function is resolved
at compile time, then static binding is used. - When a reference to a member function can only be
resolved at run-time, then this is called dynamic
binding.
17Examples of Static Binding
- i 2 3
- f 2.0 3.0
- result method(data)
In each case shown, the addresses of the
methods and members are known at compile time
18Example of Dynamic Binding
- Stack stackPtrArray100
- Stack pStack
-
- cin gtgt selection
- switch(selection)
-
- case 1 pStack new OpStack
- break
- case 2 pStack new InvertedStack
- break
-
- stackPtrArraynext pStack
- ...
- stackPtrArrayi-gtdisplay()
we dont know what the user will enter here
19Binding and Polymorphism
- The three types of polymorphism
- Overloading functions (static binding)
- Using class templates (static binding)
- In a class hierarchy, a single call can be used
to call various methods in derived classes
(dynamic binding) - Polymorphism with static binding is called ad
hoc polymorphism
20Polymorphism
- The term polymorphism, when used without the ad
hoc qualifier, refers to calling various methods
in derived classes, with run-time binding
21Another Example
- Say you have three classes of vehicles
- Car
- Boat
- Plane
- These all move in different ways
- You can define a different move method for each
of these three
22Example (continued)
- Now move is a polymorphic method, as it does
different things depending on the class of the
object
23Limitations
- Polymorphic methods can be used for a base class
and its derived classes only - So there is a relationship between polymorphism
and inheritance
24Approach
- You can bubble up behaviors of objects in an
inheritance tree, and create a virtual method in
the base class - Then you can define different specific behaviors
in each of the derived classes - The result is that a call to one method performs
specialized actions depending on the class of the
object
25Advantages
- Polymorphism allows you to do the same work with
less code (no case statement, no data type to
check) - Your design can be more abstract when you can
just specify move without sweating the details
of how different things move - You can extend the code to include new objects
without rewriting existing code
26Extensibility
- Using virtual functions and polymorphism the code
can be extended to handle new types with
virtually no effect on the existing code.
27Abstract and Concrete Classes
- Abstract classes represent concepts for which
objects cannot exist. - Concrete Classes are used to instantiate objects.
28Using our old Example
29The Class Shape
- class shape
- public
- shape(...)
- virtual void translate(int, int)
- virtual void show()
- ...
30- void translate(int x, int y)
-
- cout ltlt Error - nothing to translate!!\n
-
- void show()
-
- cout ltlt Error - nothing to show!!\n
31Pure Virtual Function
- class shape
- public
- shape (...)
- virtual void translate(int, int) 0
- virtual void show() 0
- ...
32An Abstract Class
- A class that has one or more virtual functions is
an abstract class
33The Class Rectangle
- class rectangle public shape
-
- public
- rectangle(int, int)
- void translate(int x, int y) ...
- void show() ...
- private
- int length, width
34An Abstract Derived Class
- If, in a derived class, a pure virtual function
is not defined, then the derived class is also
considered an abstract class. - when a derived class does not provide an
implementation of a virtual function the base
class implementation is used. - It is possible to declare pointer variables to
abstract classes.
35- enum color blue, red, green
- class shape
- public
- shape(char, float, float, color)
- virtual float area() 0
- virtual void print()
- virtual shape() delete title
- private
- float xpos, ypos
- char title
- color col
-
36- shapeshape(char t, float x, float y, color c)
- xpos(x), ypos(y), color(c)
-
- title new charstrlen(t)1
- strcpy(title, t)
-
- virtual void shapeprint()
-
- cout ltlt Name ltlt title ltlt endl
- cout ltlt Position ltlt xpos ltlt , ltlt ypos ltlt
endl - // ... color ...
-
37- class circle shape
- public
- circle(char, float, float, color, float)
- float area()
- void print()
- circle()
- private
- float radius
38- circlecircle(char t, float xp, float yp,
- color c, float r)
- shape(t, xp, yp, c), radius(r)
- float circlearea() return 3.14radiusradius
- void circleprint()
-
- shapeprint()
- cout ltlt radius ltlt radius ltlt endl
39- class rectangle shape
-
- public
- rectangle(char, float, float,
- color, float, float)
- float area()
- void print()
- rectangle()
- private
- float length, width
40- rectanglerectangle(char t, float x, float y,
- color c, float l, float w)
- shape(t, x, y, c), length(l), width(w)
- float rectanglearea()return lengthwidth
- void rectangleprint()
-
- shapeprint()
- cout ltlt Length ltlt length ltlt endl
- cout ltlt Width ltlt width ltlt endl
-
41- void print(shape ptr, int size)
- int main(void)
-
- shape p10
- circle c(circle one, 10, 12.5, green, 4)
- rectangle r(rect. one, 7.5, 9.2, red, 4, 5)
- ...
- p0 c
- p1 r
- p2 new circle(circle two, 2, 2.5, blue,
6.5) - print(p, 3)
- return 0
-
42- void print(shape ptr, int size)
-
- int i
- for(i0 iltsize i)
-
- ptri-gtprint()
- cout ltlt Area ltlt ptri-gtarea() ltlt endl
-