Lab 9 Re-cap, Chapter 12: Polymorphism Using Sound in Java Applications

Session 18
Lab 9 Re-cap,
Chapter 12: Polymorphism &
Using Sound in Java Applications
Decorated Ball
import java.awt.*;
public class DecoratedBall extends MovableBall
private MovableBall workerBall;
public DecoratedBall( MovableBall aBall )
workerBall = aBall;
protected MovableBall worker()
return workerBall;
public void move()
public void paint( Graphics g )
workerBall.paint( g );
public void setColor( Color newColor )
workerBall.setColor( newColor );
public Color color()
return workerBall.color();
protected int radius()
{ return workerBall.radius(); }
Decorated Ball
protected int x()
protected int y()
{ return workerBall.x(); }
{ return workerBall.y(); }
protected Rectangle region() { return workerBall.region(); }
protected void moveTo( int x, int y )
workerBall.moveTo( x, y );
protected void setMotion( double ndx, double ndy )
workerBall.setMotion( ndx, ndy );
protected double xMotion()
return workerBall.xMotion();
protected double yMotion()
return workerBall.yMotion();
Decorated Ball
public class ExpandingBall extends DecoratedBall {
public ExpandingBall( MovableBall aBall )
super( aBall );
public void move ()
region().height = ( region().height * 11 ) / 10;
region().width = ( region().width * 11 ) / 10;
Decorated Ball
public class DeceleratingBall extends DecoratedBall
public DeceleratingBall( MovableBall aBall )
super( aBall );
public void move()
setMotion( xMotion() * 0.95, yMotion() * 0.95 );
Chapter 12: Polymorphism
• polymorphism comes from the Greek root for “many
• polymorphism is about how we can use different
objects in the same place in our program, i.e.,
polymorphism depends on objects that are
substitutable for one another
• In object-oriented languages, polymorphism results
– the is-a relationship of inheritance,
– the mechanisms of message passing, and
– concept of substitutability and polymorphic variables
Polymorphic Variable
• A polymorphic variable can hold many
different types of values
– Example: “PinBallTarget target” can be
assigned a “Hole”, “ScorePad”, etc.
• Object-oriented languages often restrict
the types of values to being subclasses of
the declared type of the variable.
Varieties of Polymorphism
• Pure polymorphism - a single function
(code body) can operate on data of any
• overriding
• deferred methods / generics
• overloading / ad hoc polymorphism –
multiple functions (code bodies) with
the same name each handle a different
data type
Pure Polymorphism
• In dynamically-typed languages (e.g., Scheme) we can write
one function that operate on data of any type:
(define (sum-of-squares x y)
(+ (square x) (square y) ) )
– neither the types of the formal parameters (x and y) or the result is
known until run-time
– sum-of-squares is not even limited to operating on numeric types
– The only requires are that
• the square operator knows how to handle x’s and y’s type
• the + operator knows how to handle arguments of (square x)’s and
(square y)’s types (In Java, that could be two Strings!)
• Some OOP languages like Smalltalk are dynamically-typed
and support pure polymorphism at the method level
Overloading / Ad hoc Polymorphism
• Multiple function bodies have the same name with
each operating on different types of data
• This common name is said to be overloaded
• In strongly-typed language (i.e., Java), the compiler
can often determine the appropriate function and
generate only a single code sequence
• Different forms of overloading exist
– Overloading from separate classes: the same method
name (or operator) is used by different classes that are not
linked by inheritance (e.g, +, isEmpty())
– Parametric overloading: the same method name is used
in the same class, but with different argument signatures
Overloading from Separate Classes
• All object-oriented languages permit the form of
• Resolution of the overloaded name by the
compiler is easy by observing the class of the
receiver, e.g., myVector.isEmpty()
• Not bad programming style either if the name is
meaningful in each class
• The meaning might be complete different (i.e.,
dissimilar) in each class, e.g.,
– “draw” in a card class, and
– “draw” in a circle class
Parametric Overloading
• the same method name is used in the same
class, but with different argument signatures
• Constructor methods often use parametric
overloading, e.g., the Rectangle class
Rectangle(int width, int height)
Rectangle(int width, int height, int x, int y)
Rectangle(Point origin)
Rectangle(Dimension widthAndHeight)
Rectangle(Point origin, Dimension widthAndHeight)
• Any method (not just constructors) can be
overloaded as long as each method has a
distinct argument signature
• The superclass has a general method, say
doSomething(), but a subclass defines a
method with the same name that hides
access to the superclass’s method.
• Two different forms of overriding:
– replacement – code from the parent class is
not executed at all
– refinement – parent’s code is executed from
the subclasses code by using
Number - Abstract Class Example
• Parent class for numeric wrapper classes:
Integer, Long, Double, etc.
• Subclasses must override abstract methods
public abstract class Number {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue()
public byte byteValue() {return (byte) intValue;}
public short shortValue() {
return (short) intValue();
} // end Number
• Many languages are statically-typed, that is, they require us to
declare the type of a variable in our code. Ada generics and C++
templates are constructs that provide polymorphism of this sort, in a
statically-typed way. Java 5.0 (aka Java 1.5) supports generic
classes, too!
template <class Worker>
public class Decorator {
Worker myInstanceVariable;
public Worker getValue() { return myInstanceVariable; }
• This allows me to create decorators for objects of any type:
– Decorator<int>
– Decorator<Ball>
• This mechanism enables programmers to create nearly-pure
polymorphism by declaring the kind of object that can be "wrapped".
The template gives enough information that the compiler can verify
that the polymorphic behavior will exist at run-time.
Efficiency and Polymorphism
• The use of polymorphism tends to
optimize program development time and
reliability by aiding in ability to reuse code
• However, the trade-off is that at run-time
the execution is slightly slower