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

advertisement
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 )
{
super();
workerBall = aBall;
}
protected MovableBall worker()
{
return workerBall;
}
// *** MESSAGES DELEGATED TO THE INSTANCE VARIABLE
public void move()
{
workerBall.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 ()
{
super.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()
{
super.move();
setMotion( xMotion() * 0.95, yMotion() * 0.95 );
}
}
Chapter 12: Polymorphism
• polymorphism comes from the Greek root for “many
forms”
• 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
from:
– 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
type.
Most
• overriding
• deferred methods / generics
• overloading / ad hoc polymorphism –
multiple functions (code bodies) with
the same name each handle a different
data type
Least
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
overloading
• 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()
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
Overriding
• 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
“super.doSomething()”
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
Generic
• 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
Download