CSE 501N Fall ‘06 02: Machine Overview + Fundamental Types

Download Report

Transcript CSE 501N Fall ‘06 02: Machine Overview + Fundamental Types

CSE 501N
Fall ‘09
15: Polymorphism
October 22, 2009
Nick Leidenfrost
Lecture Outline

Lab 5 questions

Review: Inheritance

Polymorphism

Mid-semester review
2
Inheritance

Inheritance allows us to create more specific types
from existing classes

This promotes:


Code Reuse

Maintainability
We can change the behavior that we inherit by:

Overriding inherited methods

Adding behavior via new members

Fields (Instance Variables)

Methods
3
Inheritance Design Issues
(When should we use inheritance?)

Every derivation should be an is-a relationship

Child classes should define more specific behavior

Think about the potential future of a class hierarchy,
and design classes to be reusable and flexible

Find common characteristics of classes and push
them as high in the class hierarchy as appropriate

Override methods as needed to tailor or change the
functionality of a subclass

Add new variables to children, but don't redefine
(shadow) inherited variables, if possible
4
Inheritance Design Issues

Allow each class to manage its own data; use the
super reference to invoke the parent's constructor to
set up its data

Even if there are no current uses for them, override
general methods such as toString and equals with
appropriate definitions

Use abstract classes to represent general concepts
that lower classes have in common

Use visibility modifiers carefully to provide needed
access without violating encapsulation
5
Polymorphism

Polymorphism is an object-oriented concept that
allows us to create versatile software designs

We will look at on
 polymorphism
and its benefits
 using inheritance to create polymorphic references
 using interfaces to create polymorphic references
6
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
7
Binding

Consider the following method invocation:
obj.doSomething();

At some point, this invocation is bound to the
definition of the method that it invokes

If this binding occurred at compile time, then that
line of code would call the same method every time

However, Java defers method binding until run time

What we lose in predictability, we gain in program
design flexibility
8
Polymorphism

Suppose we create the following reference
variable:
Animal animal;

Java allows this reference to point to an Animal
object, or to any object of any compatible type

This compatibility can be established using
inheritance or using interfaces

Careful use of polymorphic references can lead
to elegant, robust software designs
9
Polymorphism

Consider an abstract class (or interface)
Lender, meant to model a credit facility
generally:
public abstract class Lender {
public abstract double borrow (double amount);
public abstract double repay (double amount);
public class CreditCard extends Lender {
// ... }
}
public class LineOfCredit extends Lender {
// ...
}
10
Polymorphism

A variable with an abstract class for a type holds
reference to object of a class that extends
Lender and implements its abstract methods.
Lender x;
x = new CreditCard();
x = new LineOfCredit();

Note that the object to which x refers doesn't
have type Lender; the type of the object is
some subclass of Lender.
11
Polymorphism

You can call any of the methods defined
on the variable type:
double remainingFunds = x.borrow(1000);
Which method is called?
 The borrow method defined by the
LineOfCredit class is called, because
(per the previous slide) it is the current
type stored inside variable x.

12
Polymorphism




Which method is invoked depends on the
actual object referenced.
If x refers to a LineOfCredit object, Java
Invokes LineOfCredit’s borrow method
If x refers to a CreditCard object, Java
invokes CreditCard’s borrow method
Behavior can vary depending on the actual
type of an object stored in x
notice that we are able to deal with x
uniformly as a Lender regardless of what is actually
stored inside
 However,
13
Polymorphism

Java doesn’t know at compile time what type of
object is stored within a polymorphic variable
 So
how does it know what version of a method to
call?

It uses late binding: the method call is resolved
at runtime
 a.k.a.

dynamic binding
Different from overloading; overloading is
resolved by the compiler (early binding)
14
Polymorphism via Interfaces

An interface name can be used as the type of an
object reference variable
Speaker current;

The current reference can be used to point to any
object of any class that implements the Speaker
interface

The version of speak that the following line invokes
depends on the type of object that current is
referencing
current.speak();
15
Polymorphism
via Interfaces


Suppose two classes, Professor and Dog, both
implement the Speaker interface, providing distinct
Blah blah blah.
versions of the speak method
I’m really boring.
In the following code, the first call to speak invokes
Blah
blah blah.
one version and the second
invokes
another:
Ruff. (Walk? Did you
Speaker guest = new Professor();
say Walk? Treat? I
guest.speak();
thought I heard “treat”
guest = new Dog(); somewhere in there.)
guest.speak();
16
References and Inheritance

An object reference can refer to an object of its class, or to an
object of any class related to it by inheritance

For example if we have a SavingsAccount object, then a
variable of type BankAccount could be used, if the
SavingsAccount class is derived from BankAccount
BankAccount
SavingsAccount
BankAccount acct;
...
acct = new SavingsAccount();
17
Inheritance and Assignment

Assigning a child object to a parent reference is considered to
be a widening conversion, and can be performed by simple
assignment
SavingsAccount savings = new SavingsAccount();
BankAccount account = savings;

Trust me Java, I know
Assigning an parent object to a child reference
can be done
this is a
also, but it is considered a narrowing conversion
and must be
SavingsAccount
done with a cast
BankAccount account = new SavingsAccount();
SavingsAccount savings = (SavingsAccount)account;

The widening conversion is the most useful
18
Polymorphism

As we have seen, in Java, type of a variable
doesn't definitively determine type of object to
which it refers
BankAccount aBankAccount = new SavingsAccount(1000);
// aBankAccount holds a reference to a SavingsAccount

Method calls are determined by type of actual
object, not type of object reference
BankAccount anAccount = new CheckingAccount();
anAccount.deposit(1000);
// Calls "deposit" from CheckingAccount
19
Polymorphism

Compiler needs to check that only legal
methods are invoked
Object anObject = new BankAccount();
// ...
anObject.deposit(1000); // Compile-time Error!

Why is this not allowed?
Object anObject = new BankAccount();
// Acceptable ways of casting:
((BankAccount)anObject).deposit(1000);
BankAccount account = (BankAccount)anObject;
account.deposit(1000);
20
Polymorphism


Polymorphism: ability to refer to objects of
multiple types with varying behavior
Polymorphism at work:
public void transfer (double amount, BankAccount other) {
this.withdraw(amount);
other.deposit(amount);
}

Depending on types of amount and other,
different versions of withdraw and deposit
are called
 We
don’t have to worry about the exact types we are
working with
21
Polymorphism via Inheritance

Consider the following class hierarchy:
StaffMember
Volunteer
Employee
Executive
Hourly
22
Polymorphism via Inheritance

Now let's look at an example that pays a
set of diverse employees using a
polymorphic method
[Example on board]
23
Conclusion
I will be in Lab now for help with Lab 5
 Lab 6 will be assigned on Tuesday

 (Enjoy
your weekend)
24