Polymorphism
Polymorphism in Programming Languages
A Taxonomy of Polymorphism
Overloading and Dynamic Binding
Summary
Polymorphism - Background
According to E. A. Mitscherlich (Chemist, 1794-1863)
The property of a substance to exist in different
forms of appearance (modifications)
They are build from the same atoms but differentiate in
spatial arrangement of their structure (which have
different properties).
Different grid structures are the consequence of impacts
like pressure or temperature
Example
Graphite, diamond are modifications of carbon.
© Horst Lichter, RWTH Aachen University 2
© Horst Lichter, RWTH Aachen 3
Polymorphism in Programming
Polymorphism is the ability of something to have different
appearances or shapes
In programming
something: variables, functions, procedures, objects
shape: type
A polymorphic entity can be used in different contexts requiring
different types!
[Link](100)
[Link]("100")
© Horst Lichter, RWTH Aachen University 4
Monomorphic and Polymorphic Languages
Monomorphic languages
Functions, procedures and their parameters have a unique type
Every value and every variable is of one and only one type
Examples: MODULA, Pascal WriteInt(100)
WriteString('100')
Polymorphic languages
Values and variables may have more than one type
Polymorphic functions
Actual parameters can have more than one type
Polymorphic types
Define operations that are applicable to actual parameters of more than
one type
Examples: Ada, Smalltalk, Java
© Horst Lichter, RWTH Aachen University 5
Example: Polymorphism
Inheritance is a means to realize polymorphism in object oriented
languages.
a DisplayableRectangle behaves like
a Rectangle and like a DisplayableObject
GeoObject DisplayableObject
DisplayableRectangle dr;
dr = new DisplayableRectangle();
Rectangle
[Link] (p);
x = [Link](); Rectangle
DisplayableRectangle [Link] (p);
s = [Link]();
DisplayableObject
© Horst Lichter, RWTH Aachen University 6
© Horst Lichter, RWTH Aachen 7
Polymorphism - Taxonomy
Parametric
Polymorphism
Universal
Polymorphism Inclusion
Polymorphism
Polymorphism
Operator
Overloading
Ad-hoc
Polymorphism
Type Coercion
Cardelli, L., Wegner, P. (1985): On Understanding Types, Data Abstraction, and Polymorphism,
ACM Computing Surveys, Vol. 17, No. 4
© Horst Lichter, RWTH Aachen University 8
Universal and Ad-hoc Polymorphism Parametric
Polymorphism
Universal
Universal polymorphism
Polymorphism Inclusion
Polymorphism
Synonym: true polymorphism
Polymorphism
Operator
Overloading
Ad-hoc
Polymorphism
Universal polymorphic operation is applicable for Type Coercion
a potentially infinite number of different types
Have a partially common structure
The same code is executed for all admissible different types
Ad-hoc polymorphism
Synonym: apparent polymorphism
Ad-hoc polymorphic operation is applicable on finite set of different types
Does not necessarily behave the same
Different types must not have commonalities
Depending on the parameter type the operation executes different code
May be seen as a finite set of monomorphic operations
© Horst Lichter, RWTH Aachen University 9
Parametric Polymorphism Parametric
Polymorphism
Universal
Polymorphism Inclusion
Polymorphism
Polymorphism
Operator
Overloading
Ad-hoc
Polymorphism
Type Coercion
Operation usually has one ore more type parameters which determine the type of
the arguments for each application.
input, output and result
Admissible types usually have a common structure
Using parametric polymorphism, a function or a data type can be written
generically.
It can handle values identically without depending on their type.
Are called generic functions and generic data types (classes)
© Horst Lichter, RWTH Aachen University 10
Generics - Example
generic
type Element_type is private;
type Index_type is (<>);
type Array_type is array (Index_Type range <>) of Element_type;
with function “<“ (Left, Right : Element_type) return Boolean is <>;
procedure max (ar in out Array_type);
subtype Range_type is Integer range 1 .. 100;
procedure integer_max is new max(Integer, Range_type, "<");
public class CollectionUtil {
public static <T extends Comparable<T>> T max (Collection<T> collection) {
Iterator<T> iter = [Link]();
T value1 = [Link]();
while ([Link]()) {
T value2 = [Link]();
if ([Link](value2) < 0)
value1 = value2;
}
return value1;
}
}
© Horst Lichter, RWTH Aachen University 11
Inclusion Polymorphism Parametric
Polymorphism
Universal
Polymorphism Inclusion
Polymorphism
An object can be viewed as belonging to Polymorphism
many different classes, that need not be disjoint.
Operator
Overloading
Ad-hoc
Polymorphism
There may be inclusion of classes Type Coercion
Subtyping realizes inclusion polymorphism
Objects of a subtype can be manipulated as if belonging to their
supertypes
DisplayableObject
Displayable Displayable Rectangles
Rectangle Objects Rectangles
DisplayableRectangle
© Horst Lichter, RWTH Aachen University 12
Overloading and Type Coercion Parametric
Polymorphism
Universal
Overloading of operations
Polymorphism Inclusion
Polymorphism
Polymorphism
Purely syntactic way of using the same name Operator
Overloading
for different operations Ad-hoc
Polymorphism
Context information (types of arguments) is needed Type Coercion
to decide what operation to execute
The compiler can resolve the ambiguity at compile time
Type coercion
Coercion is a semantic operation needed to convert an argument to the
expected type
Programmer needs not to specify type conversions that are semantically
necessary
Type conversions are determined by the compiler and inserted to generate
the respective conversion code
© Horst Lichter, RWTH Aachen University 13
Example: Overloading and Coercion
Example
1. 3 + 4
2. 3.0 + 4
3. 3 + 4.0
4. 3.0 + 4.0
Possible alternatives of applying ad-hoc polymorphism ????
© Horst Lichter, RWTH Aachen University 14
© Horst Lichter, RWTH Aachen 15
Redefinition versus Overloading
© Horst Lichter, RWTH Aachen 16
Redefinition
public boolean equals(Object o) {
if (o instanceof Point) {
Point p = (Point) o;
return (y == p.y) && (x == p.x);
}
else return false;
}
public boolean equals(Object o) {
if (o instanceof ColouredPoint) {
ColouredPoint p = (ColouredPoint) o;
return ([Link](p)) && c == p.c;
} else return false;
}
© Horst Lichter, RWTH Aachen 17
Overloading
public boolean equals (Point p){
return (y == p.y) && (x == p.x);
}
public boolean equals (ColouredPoint p){
return ([Link](p)) && (c == p.c);
}
© Horst Lichter, RWTH Aachen 18
Redefinition versus Overloading
public boolean equals(Object o) { public boolean equals (Point p){
if (o instanceof Point) { return (y == p.y) && (x == p.x);
Point p = (Point) o; }
return (y == p.y) && (x == p.x);
} public boolean equals (ColouredPoint p){
else return false; return ([Link](p)) &&
} color == [Link];
}
public boolean equals(Object o) {
if (o instanceof ColouredPoint) {
ColouredPoint p = (ColouredPoint) o;
return ([Link](p)) && c == p.c;
} else return false;
}
Point p1 = new Point(1,1);
ColouredPoint c1 = new ColouredPoint(1,1, 200);
Point p2 = new Point(0,0);
Redef. Overl.
[Link](p2)
[Link](c1)
[Link](p1)
© Horst Lichter, RWTH Aachen 19
The Yoyo Effect
Taenzer, D. et al. (1989): Object-Oriented Software Reuse: The Yoyo Problem.
JOOP, Vol. 2, No. 3, pp 30-35.
draw getBitmap
void draw(){
[Link]();}
getFactor
draw
void draw(){
[Link]();
[Link]();}
draw getTransMode
void draw(){
[Link](); TranspIcon myIcon = new TranspIcon();
[Link]();} [Link]();
© Horst Lichter, RWTH Aachen 20
The Yoyo Effect
draw
void draw(){ getBitmap getFactor
[Link]();} draw
void draw(){
[Link]();
[Link]();} draw getTransMode
TranspIcon myIcon = new TranspIcon();
[Link]();
Redefinition of methods in a hierarchy may
void draw(){
[Link](); change the behaviour of other exisiting
[Link]();} methods!
© Horst Lichter, RWTH Aachen 21
Dynamic Binding
public static void main(String[] args){
Dynamic binding:
GeoObject g;
Rectangle r = new Rectangle (4,6); Looking for the right implementation
Circle c = new Circle (4.5); at run-time.
Double a;
g = c;
a = [Link]();
g = r;
a = [Link]();
}
© Horst Lichter, RWTH Aachen University 22
Static and Dynamic Types
Each variable has a static type (by declaration) static type
GeoObject g;
Rectangle r = new Rectangle (4,6);
Circle c = new Circle (4.5);
g = c; dynamic type
By means of g = r;
assignment or parameter passing objects of other (dynamic) types can be bound
to a variable.
Task of the type checker
In a polymorphic assignment only types that are subtypes of the static type are
admissible
This rule guarantees that all called operations exist
Task of the run-time system
bind the right operation implementation to the message
© Horst Lichter, RWTH Aachen University 23
Method look-up - 1
Single dispatch
Search for the method is only based on the receiver of the message
a plus(b)
The class of the object bound to a variable determines the method that is
executed
Argument objects do not contribute to the decision
Even conceptually symmetric methods are executed asymmetrically.
Multiple dispatch
The types of all arguments together determine which method is executed
plus(a, b)
No emphasized message receiver
© Horst Lichter, RWTH Aachen University 24
Example – Double Dispatch
Scenario
There are several kinds of
graphics, e.g.: Bitmap, VectorGraphic
media, e.g.: PDFFile, PSFile
The algorithm to print a graphic on a medium depends on both the graphic
and the medium
How can we simulate multiple dispatch in Java?
class Printer
print (bm, pdf)
print (bm, ps)
print (vg, pdf)
print (vg, ps)
© Horst Lichter, RWTH Aachen University 25
Solution 1 : Using Meta-Information
public class Printer {
public static void print (Graphic g, Medium m){
[Link](g);
}
}
public abstract class Medium {
public void print (Graphic g) {
[Link](this);
}
} public abstract class Graphic {
public abstract void printOn (Medium m);
}
public class Bitmap extends Graphic {
public void printOn(Medium m) {
if (m instanceof PDFFile){
[Link]("Bitmap is printed on a PDF file");
}
if (m instanceof PSFile){
[Link]("Bitmap is printed on a PS file");
}
...
© Horst Lichter, RWTH Aachen University 26
Solution 2: Using Type-dependent Methods
public class VectorGraphic extends Graphic {
public void printOnPDF(Medium m) {
[Link](“VG is printed as a PDF file");
}
public void printOnPS(Medium m) {
[Link](“VG is printed as a PS file");
}
}
© Horst Lichter, RWTH Aachen University 27
Solution 2: Dispatching the Call
public class PDFFile extends Medium {
public void print(Graphic g) {
[Link](this);
}
}
public class PSFile extends Medium {
public void print(Graphic g) {
[Link](this);
}
}
© Horst Lichter, RWTH Aachen University 28
Solution 2: Dispatch Chain
PDFFile pdf = new PDFFile();
VectorGraphic vg = new VectorGraphic();
[Link](vg, pdf)
© Horst Lichter, RWTH Aachen University 29
Polymorphism and Open Constructions
print only depends on class
DisplayableObject
print can be used unchanged, even if new subclasses of DisplayableObject are added.
Construction is open and can be extended easily!
© Horst Lichter, RWTH Aachen University 30
Type safety <-> Flexibility
Static strong typing
&
Dynamic binding
lead to:
Safety through type system (no run-time errors)
Flexibility realized by polymorphism and dynamic binding
© Horst Lichter, RWTH Aachen University 31
Summary
Polymorphism is a means to create program entities that can be used
in different context.
Universal polymorphism
Ad-hoc polymorphism
Inheritance yields to subtype polymorphism
Dynamic binding is needed to find the right implementation of
methods at run-time
We can build open and flexible design that can be extended
© Horst Lichter, RWTH Aachen University 32