Polymorphism

Download Report

Transcript Polymorphism

Polymorphism
Polymorphism

The term polymorphism literally means "having
many forms"

A polymorphic reference is a variable that can refer
to different types of objects at different points in time

The method invoked through a polymorphic
reference can change from one invocation to the
next

All object references in Java are potentially
polymorphic
Example

Perfectly legal:
Shape s1;
Rectangle r = new Rectangle(…);
s1=r;
Shape s2 = new Rectangle(…);
Object o = new Circle(…);

Not legal:
Shape s = new Circle;
Rectangle r = s;
What Gets Checked at Compile-Time?


Validity of assignments
Can cause non-obvious restrictions:
Shape s = new Rectangle(…);
Rectangle r = s; \\ is this still a rectangle?

Checking validity of assignments at compile
time lets programs run faster
Casting

If you really need a more specific type, you
can do this:
Shape s = new Rectangle(…);
Rectangle r = (Rectangle) s;

But this can be dangerous, and should
generally be avoided
Late Binding: Which Method?

Consider:
Shape s = new Rectangle(…);
String myOutput = s.toString();

If toString was defined in Shape then
overridden in Rectangle, which definition
should be used?

s is a Shape reference:


Use the one from Shape?
s actually refers to a Rectangle

Use the one from Rectangle?
Which Method?

Java follows the reference to the actual
instance


The instance method is what gets used


the reference is just pointing to the thing we use
Rectangle
This is called late binding… Java doesn’t
decide which method gets called until the
method is encountered at run-time
Why?

Let’s you use a more generic reference when
needed, but still get the right reference
public void draw(Collection<Shape> shapes)
{
for(Shape s: shapes)
s.draw();
}

Different shapes will have different draw
methods

… but this will use the right one in each case
Also Works with Interfaces
public boolean startsWith(List<int> list, int val)
{
return list.get(0)==val;
}

Whether the argument is an ArrayList,
Vector, or LinkedList, this method works

uses the .get(…) method from the appropriate
underlying implementation
Late Binding Works Everywhere

Interface, Abstract Class, Non-Abstract Class




can declare a reference to any of these
any object that inherits/implements the reference
type can be used for the reference
any method that is defined by the reference can
be used
the implementation in the actual instance will be
called
A Caveat from the Text


Consider interface Speaker, with method
speak()
Suppose Dog and Philosopher both
implement Speaker
Speaker guest;
guest = new Philosopher();
guest.speak();
guest = new Dog();
guest.speak();
A Caveat from the Text

Now suppose Philosopher also includes a
method pontificate()

Then this does not work:
Speaker special = new Philosopher();
special.pontificate();

Method called must be in the interface
Example: The Coffee Bar

Ordering at a coffee bar



espressos, coffee, low-fat milk, etc…
lots of structure, lots of subtypes, lots of
polymorphism
We want to represent orders taken, these can
be passed on to make the drinks
How Hard is This?
© Starbucks 2005, “Make it Your Drink”
Stuff to Represent



Cup (to-go, for-here, iced, personal cup)
Size (small, medium, large)
Shots (1 or more espresso, caf/decaf)





default determined by size, but can be changed
Syrups (0 or more flavour shots)
Milk (whole, 2%, skim, soy)
Toppings (whipped cream, caramel)
Drink (espresso shot, Americano, mocha…)
Class Hierarchy
Implementation

….