Polymorphism
Download
Report
Transcript Polymorphism
Polymorphism
3 main programming mechanisms
that constitute OOP:
1.
2.
3.
Encapsulation
Inheritance
Polymorphism
Polymorphism
The ability to associate many meanings to
one method name by means of a special
mechanism known as late binding or
dynamic binding.
Allows one to make changes in the method
definition for the derived classes and have
those changes apply to the software written
in the base class.
Late binding
AKA dynamic binding
Binding – the process of associating a
method definition with a method invocation
Early binding – the method definition is
associated with the method invocation when
the code is compiled; AKA static binding
Late binding – the method invocation is
associated with the method invocation when
the method is invoked (at run time)
Java uses late binding except for a few cases.
Late binding example
Figure
draw() method that draws a point
center() method that moves the object to the
center of the screen and calls draw()
superclass for drawing with the following
subclasses:
Rectangle
Circle
draw() method that draws a rectangle
draw() method that draws a circle
Oval
draw() method that draws an oval
Late binding example
We add a new subclass of Figure
called Triangle.
Do we need to recompile Figure
(because Figure’s center() method will
call Triangle’s draw() method)?
Late binding example
We add a new subclass of Figure
called Triangle.
Do we need to recompile Figure
(because Figure’s center() method will
call Triangle’s draw() method)? NO!
What mechanism makes this work?
Late binding example
We add a new subclass of Figure
called Triangle.
Do we need to recompile Figure
(because Figure’s center() method will
call Triangle’s draw() method)? NO!
What mechanism make this work?
Late binding!
Late binding example
What would happen (when Figure’s
center() calls draw() for a Triangle) if
we didn’t have late binding but had
early binding instead?
Late binding example
What would happen (when Figure’s
center() calls draw() for a Triangle) if
we didn’t have late binding but had
early binding instead?
Figure’s draw() would be called instead of
Triangle’s draw().
Late binding
Late binding is not “free.”
Some additional overhead at runtime
is required.
final
Recall the final keyword.
What happens for an instance variable?
What happens for a method?
What happens for a class?
Late binding exceptions
Java does not use late binding with:
Private methods
Methods marked final
Static methods
Static binding is used instead.
Static binding & static methods
public class Sale {
//…
public static void announcement ( ) {
System.out.println( “This is the Sale class.” );
}
}
public class DiscountSale extends Sale {
//…
public static void announcement ( ) {
System.out.println( “This is the DiscountSale class.” );
}
}
public class Sale {
public static void announcement ( ) {
System.out.println( “This is the Sale class.” );
}
public void showAd ( ) {
System.out.println( “buy sale” );
}
}
public class SaleTest {
public class DiscountSale extends Sale {
public static void main ( String args[] ) {
public static void announcement ( ) {
Sale s = new Sale();
System.out.println( “This is the DiscountSale class.” );
DiscountSale d = new DiscountSale();
}
public void showAd ( ) {
s.announcement(); //ok
System.out.println( “buy discount sale” );
d.announcement(); //ok
}
}
s.showAd(); //ok
d.showAd(); //what?
s = d;
s.announcement();
//what?
System.out.println( s.toString() );
s.showAd(); //ok
d.showAd(); //what?
}
}
Downcasting & upcasting
Casting
What are casts?
Where have we seen/used casts
before?
Casting
What are casts?
Converting from one type to another
Where have we seen/used casts
before?
double d = 0.9;
int i1 = (int) d;
int i2 = (int) (d + 0.5);
Downcasting and upcasting
Upcast = assigning an object of a derived
class to a variable of a base class (or any
ancestor class)
straightforward
Downcast = a type cast from a base class to
a derived class (or from any ancestor class
to any descendent class)
troublesome
Downcasting
When impossible, it will generate an
error at either compile time or a run
time.
Required by equals() method (when
downcasting from Object)
instanceof may be used to check if
downcast will work
clone() method
clone() method
defined in Object as:
protected Object clone()
every object inherits a clone() method
(supposed to) return a deep copy of the
calling object
you are expected to override it
like a copy ctor but there are cases where
clone() works but the copy ctor does not.
Unofficial version of clone()
public Class_Name clone ( ) {
return new Class_Name( this );
}
Later, we will define the “official” version.
Cloning array elements
public static Sale[] goodCopy ( Sale a[] ) {
Sale b[] = new Sale[ a.length ];
for (int i=0; i<a.length; i++)
b[i] = a[i].clone();
return b;
}
Does this work? Yes.
Does this provide a “deep” copy? Yes, as long
as clone() does.
Cloning array elements
public static Sale[] goodCopy ( Sale a[] ) {
Sale b[] = new Sale[ a.length ];
for (int i=0; i<a.length; i++)
b[i] = a[i].clone();
return b;
}
Does it work if elements of a[] are not
Sale objects but are derived from
Sale?
Cloning array elements
public static Sale[] goodCopy ( Sale a[] ) {
Sale b[] = new Sale[ a.length ];
for (int i=0; i<a.length; i++)
b[i] = a[i].clone();
return b;
}
Does it work if elements of a[] are not Sale
objects but are derived from Sale? Yes.
Why?
Cloning array elements
public static Sale[] goodCopy ( Sale a[] ) {
Sale b[] = new Sale[ a.length ];
for (int i=0; i<a.length; i++)
b[i] = a[i].clone(); //polymorphic
return b;
}
Does it work if elements of a[] are not Sale
objects but are derived from Sale? Yes.
Why? Because clone() is overridden.
Cloning array elements
Does it work using a copy ctor?
public static Sale[] goodCopy ( Sale a[] ) {
Sale b[] = new Sale[ a.length ];
for (int i=0; i<a.length; i++)
b[i] = new Sale( a[i] ); //not polymorphic
return b;
}
This doesn’t work for subclasses of Sale.