Title: Session 3 Polymorphism and Dynamic Binding
1Session 3Polymorphism and Dynamic Binding
Übung Softwareentwicklung 2für
Wirtschaftsinformatik
Dr. Ismail Khalil Ibrahim, MSc.,Dr. Wieland
Schwinger, MSc.,
Object-Oriented Programming and Java, Danny C.C.
Poo and Derek B.K. Kiong, Springer, 1998
2Polymorphism
- Polymorphic of many forms
- Webster's Dictionary about "polymorphic"
- the quality or state of being able to assume
different forms as a existence of a species
in several forms independent of the variations of
sex b the property of crystallizing in two or
more forms with distinct structure - A polymorphic method is one that has the same
name for different classes of the same family but
has different implementations for the various
classes
3Overloading methods Constructors
- Overloading refers to the ability to allow
different methods or constructors of a class to
share the same name - If two methods or constructors in the same class
have different signatures, then they may share
the same name - Method Signature
- void move(int x, int y) move(int, int)
- void move(double x, double y)
move(double, double) - boolean move(int x, int y)
move(int, int) - Methods of different classes can have the same
signature
4An example - Point class
class Point private double x, y public
Point() x 0.0 y 0.0 public
Point(double x, double y) this.x x
this.y y public double distance(Point
other) double dx this.x - other.x
double dy this.y - other.y return
Math.sqrt(dx dx dy dy) public double
distance(double x, double y) double dx
this.x - x double dy this.y - y
return Math.sqrt(dx dx dy dy)
5Example cont.
- when an overloaded method is called, the number
and the types of the arguments are used to
determine the method that will be invoked
Point p1 new Point() Point p2 new
Point(20.0, 30.0) p2.distance(p1) p2.distance(50
.0, 60.0)
6Subtypes
- A subclass is a specialization of its superclass
- Every instance of the subclass is an instance of
the superclass - The type defined by the subclass is a subtype of
the type defined by its superclass
Shape
Shape
Square
Circle
7Rule of Subtype
- A value of a subtype can appear wherever a value
of its supertype can appear - If class E extends class B, any instance of E can
act as an instance of B
class Shape class Circle extends Shape
class Square extends Shape Shape
shape1, shape2 shape1 new Circle() shape2
new Square()
8Static vs dynamic binding
- Binding refers to the association of a method
invocation and the code to be executed on behalf
of the invocation. - In static binding (early binding), all the
associations are determined at compilation time. - conventional function calls are statically bound
- In dynamic binding (late binding), the code to be
executed in response to a method invocation
(i.e., a message) will not be determined until
runtime. - method invocations to reference variable
shapeArrayi (in the following example) are
dynamically bound
9Polymorphism
- The ability of different objects to perform the
appropriate method in response to the same
message is known as polymorphism - The selection of the appropriate method depends
on the class used to create the object
name getName( ) calculateArea( )
Shape
side calculateArea( )
radius calculateArea( )
Square
Circle
10Example
// Object-Oriented Programming and Java, // Danny
C.C. Poo and Derek B.K. Kiong, Springer, 1998) //
To illustrate the concept on dynamic binding, //
overriding and overloading class Shape
private String name public Shape(String aName)
nameaName public String getName( )
return name public float calculateArea( )
return 0.0f // End Shape class
11Example cont.,
class Circle extends Shape private float
radius public Circle(String aName)
super(aName) radius 1.0f public
Circle(String aName, float radius)
super(aName) this.radius radius public
float calculateArea() return (float)3.14fradiu
sradius // End Circle class
class Square extends Shape private float
side public Square(String aName)
super(aName) side 1.0f public
Square(String aName, float side)
super(aName) this.side side public
float calculateArea() return (float) sideside
// End Square class
12Example cont.,
public class ShapeDemoClient public static
void main(String argv ) Shape c1 new
Circle("Circle C1") Shape c2 new
Circle("Circle C2", 3.0f) Shape s1 new
Square("Square S1") Shape s2 new
Square("Square S2", 3.0f) Shape shapeArray
c1, s1, c2, s2 for (int i 0 i lt
shapeArray.length i)
System.out.println("The area of "
shapeArrayi.getName()
" is " shapeArrayi.calculateArea()
" sq. cm.") // End
main // End ShapeDemoClient1 class
13Polymorphism
- Polymorphism is possible because of
- inheritance subclasses inherit attributes and
methods of the superclass. - public class Circle extends Shape
-
-
- method overriding subclasses can redefine
methods that are inherited from the superclass - public class Shape
- public float calculateArea( ) return 0.0f
-
-
- public class Circle extends Shape
- public float calculateArea( ) return (float)
3.14fradiusradius -
14Polymorphism
- rule of subtype reference variables of
superclass can be used to refer object instances
of its subclasses - Shape c new Circle(Circle C)
- Shape s new Square(Square S)
- Shape shapeArray c, s,
- dynamic binding method invocations are bound to
methods during execution time - for(int i 0 i lt shapeArray.lenth i)
- shapeArrayi.calculateArea()
Circle
shapeArray
Square
c
s
Square
Triangle
Rectangle
15Incremental development
- adding new class is made easy with inheritance
and polymorphism
name getName( ) calculateArea( )
Shape
base height calculateArea( )
Triangle
Circle
Square
16Example
class Triangle extends Shape private float
base, height public Triangle(String aName)
super(aName) base 1.0f height 1.0f
public Triangle(String aName, float base,
float height) super(aName) this.base
base this.height height public float
calculateArea() return (float)
0.5fbaseheight // End Triangle class
public class ShapeDemoClient public static
void main(String argv ) Shape t
new Triangle(Triangle T, 4.0f, 5.0f)
Shape shapeArray c1, s1, c2, s2, t
for (int i 0 i lt shapeArray.length i)
System.out.println("The area of "
shapeArrayi.getName() " is "
shapeArrayi.calculateArea() " sq. cm.")
// End main // End ShapeDemoClient class
extension of array by one triangle
17Increased code readability
- polymorphism also increases code readability
since the same message is used to call different
objects to perform the appropriate behavior. - versus
for (i 0 i lt numShapes i) switch
(shapeTypei) c calculateCircleArea(
) break s calculateSquareArea( )
break
bad style!
for(int i 0 i lt shapeArray.lenth i)
shapeArrayi.calculateArea( )
18Design Hints
- use polymorphism, not type information whenever
you find the code of the form - if (x is of type 1)
- action1(x)
- else if (x is of type 2)
- action2(x)
action( )
XType
XType1
XType2
action( )
action( )
x.action( )
19Design Hints
- move common behavior to the superclass
- to floodfill a shape means to do the following
- - plot the outline of the shape
- - if it isnt a closed shape, give up
- - find an interior point of the shape
- - fill the shape
- these common behaviors can be put into the
superclass Shape
abstract class Shape public boolean
floodfill(GraphicsPanel aPanel, Color aColor)
plot(aPanel) if ( ! isClosed( ) ) return
false Point aPoint center( )
aPanel.fill(aPoint.getX( ), aPoint.getY( ),
aColor) return true
20Design Hints
- subclasses merely need to redefine plot( ),
isClosed( ), and center( ).
Floodfill( ) plot( ) isClosed( ) center( )
Shape
plot( ) isClosed( ) center( )
Triangle
Square
Circle
Shape c new Circle(Circle C) Shape s new
Square(Square S) Shape t new
Triangle(Triangle T) Shape shapeArray c,
s, t for (int i 0 i lt shapeArray.length
i) shapeArrayi.floodfill(aPanel,
aColor)
21Selbsttest
- Angenommen die Klasse Bird hat eine Methode fly()
und es gibt eine davon abgeleitete Klasse Ostrich
(Strauß), deren Objekte nicht fliegen können
sollen.Was kann man da tun?
- ... die Methode fly mit einer leeren Methode
überschreiben (oder man wirft in dieser Methode
eine CannotFly-Exception) - ... zwei neue Klassen einführen eine für
Laufvögel (RunningBird) und eine für Flugvögel
(FlyingBird), wobei nur FlyingBird eine Methode
fly hat. Die Basisklasse von beiden ist Bird
(ohne fly)
22Selbsttest
- Welche Methodenaufrufe erfordern dyn. Bindung? Wo
ist stat. Bindung möglich? - class B extends A
- B () this(3) // 1)
- B (int x) super(x) // 2)
- void k (int f)
- o() // 3)
- super.k(f - 1) // 4)
- A a new B()
- B b new B()
- a.m() // 5)
- b.m() // 6)
-
- final void m () ...
-
1) statisch es gibt nur einen möglicher
Konstruktor (der zwar überladen, aber nicht
überschrieben ist)
2) statisch nur ein möglicher Konstruktor (in
der Superklasse) vorhanden
3) dynamisch Methode o kann in einer
abgeleiteten Klasse überschrieben sein
4) statisch Supercalls sind immer statisch
gebunden, da es nur eine Methode gibt, die damit
gemeint sein kann.
5) dynamisch die Methode m der Klasse A kann
überschrieben sein (ist sie auch, von der Methode
m in der Klasse B)
6) statisch die Methode m der Klasse B kann
nicht überschrieben sein, da sie final ist und
der stat. Typ B den dyn. Typ von b auf B oder
davon abgeleitet einschränkt also kein A
möglich.
23Selbsttest
- Welche Methodenaufrufe erfordern dyn. Bindung? Wo
ist stat. Bindung möglich? -
7) statisch statische Methode
abstract class A A () ... A (int y)
... void k (int a) l() // 7)
m() // 8) n() // 9) o() //
10) static void l () ... abstract
void m () private void n () ... void o
() ...
8) dynamisch siehe Punkt 5
9) statisch die Methode könnte zwar von einer
inneren Klasse überschrieben worden sein (Java
gibt aber dem private Vorrang und bindet
statisch, d.h. private wird prinzipiell statisch
gebunden).
10) dynamisch siehe Punkt 3
24Selbsttest
- Welche Arten von inneren Klassen gibt es? Wozu
kann man diese verwenden?
- Statische innere Klassen haben keine Referenz auf
das umgebende (äußere) Objekt (Outer.Inner inner
new Outer.Inner()). z.B. für Knoten einer
Liste, wenn die Knoten keine Referenz auf die
Liste selbst benötigen. - Nicht-statische innere Klassen haben eine
Referenz auf das umgebende (äußere) Objekt
(Outer.Inner inner outer.new Inner()). z.B.
zur Simulation von Mehrfachvererbung. - Lokale innere Klassen werden in einer Methode
deklariertvoid foo() class MyClass extends
OtherClass void m() OtherClass my new
MyClass() my.m()Sie können statisch oder
nicht-statisch sein (je nach umgebender Methode).
z.B. Ersatz von Methoden-Referenzen, Ersatz von
lokalen (nur in dieser Methode benötigten)
Methoden. - Anonyme innere Klassen sind im Prinzip das
gleiche wie lokale innere Klassen, jedoch ohne
der Klasse einen speziellen Namen zu geben (gt
Kein Konstruktor möglich)void foo()
OtherClass my new OtherClass() void m()
my.m()
25Abstract Class
- Eine abstrakte Klasse ist eine Klassendefinition
von der keine Instanzen gebildet werden
könnendh. AbstractClass o new AbstractClass()
ist nicht erlaubt! - Eine abstrakte Klasse hat mindestens eine oder
mehrere abstrakte Methoden (abstract method)
d.h. die Realisierung der Methoden ist nicht
"vollstaendig". - Subklassen können von einer abstrakten Klasse
abgeleitet sein und können wiederum abstrakt
sein. - Nur von "konkreten" (d.h. nicht abstrakten
Subklassen) können Instanzen gebildet werden.
Diese müssen noch alle "fehlenden" Methoden
implementieren. - Eine abstrakte Klasse kann (wie jede Klasse) als
Typ verwendet werden d.h. AbstractClass o new
ConcreteClass() ist erlaubt. - Eine abstrakte Methode sowie eine abstrakte
Klasse werden durch das Schlüsselwort "abstract"
ausgezeichnet.
26Abstract Class
- abstract class GraphicObject
- int x, y // konkrete Attribute
- ...
- void moveTo(int newX, int newY)
- ... // konkrete Methode
-
- abstract void draw() // nur gesagt, dass
jedes - // GraphicObject eine Methode draw() können
muss -
- // Jede nicht-abstrakte Sub-Klasse muss eine
Implementierung für - // die Methode draw() zur Verfügung stellen.
- class Circle extends GraphicObject
- void draw()
- ... // konkrete Implementierung
-
-
- class Rectangle extends GraphicObject
27Beispiel Shapes
- Eine abstrakte Klasse Shape mit den zwei
Spezialisierungen Rectangle und Circle soll
modelliert werden. Geben Sie die nötigen
Attribute der Klassen an und implementieren Sie
die Methoden move und draw.Hinweis Zum Zeichnen
können Sie die Klasse Graphics verwenden class
Graphics static void drawRect(int x, int y,
int w, int h) . . . static void
drawCircle(int x, int y, int r) . . . - Gegeben Sei eine Klasse ShapeList class
ShapeList private Shape shapes
... Implementieren Sie je eine Methode zum
Zeichnen (drawAll()) und zum Verschieben
(moveAll()) aller Shapes in der Liste.
28Beispiel Shapes
- Eine abstrakte Klasse Shape mit den zwei
Spezialisierungen Rectangle und Circle soll
modelliert werden. Geben Sie die nötigen
Attribute der Klassen an und implementieren Sie
die Methoden move und draw.Hinweis Zum Zeichnen
können Sie die Klasse Graphics annehmen class
Graphics static void drawRect(int x, int y,
int w, int h) . . . static void
drawCircle(int x, int y, int r) . . . - Gegeben Sei eine Klasse ShapeList class
ShapeList private Shape shapes
... Implementieren Sie je eine Methode zum
Zeichnen (drawAll()) und zum Verschieben
(moveAll()) aller Shapes in der Liste.
29Beispiel Shapes
- public abstract class Shape protected int x,
y public Shape(int x, int y) this.x x
this.y y public abstract void draw()
public void move(int dx, int dy) x dx y
dy - public class Circle extends Shape protected
int r public Circle(int x, int y, int r)
super(x, y) this.r r public void draw()
Graphics.drawCircle(x, y, r)
- public class Rectangle extends Shape
protected int w, h public Rectangle(int x, int
y, int w, int h) super(x, y) this.w w
this.h h public void draw()
Graphics.drawRect(x, y, w, h) - public class ShapeList private Shape
shapes ... public drawAll() for(int
i0 iltshapes.length i) shapesi.draw()
public moveAll(int x, int y) for(int
i0iltshapes.lengthi) shapesi.move(x,y)