inheritance and
polymorphism
The
important
point
is
that
the
reference
type
AND
the
object
type
are
the
same.
In
this
example,
both
are
Dog.
But
with
polymorphism,
the
reference
and
the
object
you
are
here
~
185
polymorphism In action
With
polymorphism,
the
reference
type
can
be
a
superclass
of
the
actual
object
type.
When
you declare a reference variable,
any object
that
passes
the
IS-Atest for the
declared type
of
the reference variable
'fOU
~d.
to
do.
~O"
Un
fvl:.
A
NY
animals
[2)
=
new
Wolf()
;
<-
s"bclass
of
A"i al
i tnt A
i1'fl41
a
a'f!
animals
[3)
=
new
method
class
Vet
{
Inheritance
and
polymorphism
public
void
qiveShot(Animal
a)
II
do
horrible
things
to
the
Animal
at
/ /
the
other
end
of
the
'a'
parameter
a.ma.keNoise();
}
(h)
;
(
Itippo's
Or\dkeNoiseO
l"1AN;
you
are
here)
187
exploiting the power of
polymorphism
NOW
I
get
itl
If
I
write
my code using polymorphic arguments,
where.
r declare
the
method parameter as a
super-class type,
r
CM
pass in anysubclass
object
at
doutt't
have
to
chattge
whe
you
'tttroduce
ew
subclass
types
I to
the
progratlt.
Remember
that
Vet class?
If
you write
that
Vet class using
arguments
declared
as type Animal;
your
code
can
handle
any
on
.
Why is polymorphism guaranteed to
work
this way? Why Is
it always safe to assume
that
any
subclass
type will have
the
methods you
think
you're calling on
the
suoerclass
type (the
superclass reference type you're using
the
dot
operator on)?
18a
chapter
7
:the
re
l
ar
H ? 0
Diimo
there isn't a hard
limit
(well,
not
one
that
you'd ever run into) .
Q: Hey,I
just
thought
of
something if you
don't
have
Kcess
to
the
source code for a class,
but
you
want
to
change
the
way a
method
of
that
class works, could
JOu use subclassing to do
There's no such
thing
as a
private class,except in a very special
case called an
innerclass,
that
we
haven't looked at yet. But there
are
three things
that
can prevent a class
from being subclassed.
The first is accesscontrol. Even
though
a classcan'tbe marked
pr
i
va
t e, a
class
canbe non-public (what you
get
if
you don 't declare the classas
p
ub
l
ic
The third issue is
that
if a classhas
only p r i
va
te
constructors (we'll
look at constructors in chapter 9),it
can't be subclassed.
inheritance and polymorphism
Q: Whywould you ever
want
to
make a final class? What
advantage
would
there
be in preventing a class
from being subclassed?
A:
Typically, you won't make your
classes
final. But if you need security
- the security
of
knowing
that
the
methods will always
work
method
with
the
fin
almodifier
.
Mark the whole
class
asfinal if you
want
to guarantee that none
of
the
methods in
that
classwill ever be
overridden.
you are here r
189
Keepl.,g
the
co"tract:
rules
for
overriding
Appliance
boolean
bJmOnO
boolean
bJmOffO
arguments
and
I
return
a
boolean
." In
other
words,
the
arguments
and
return
types of
your
overriding
method
must
look
to the outside
world
exactly
like the
overridden
method
in
the
superclass.
The
methods
cares only
if
class
Appliance
has
the
method
you
're
invoking
on
an Appliance reference.
But at runtime,
thejVM
looks
not
at
the
reference
type (Appliance)
but
at
the
actual
Toaster
object on
the
heap. So
if
the
reference
will call
turn
On 0 as a no-
o.
h6 e \)Ie
arg
method,
even
though
there's
a version in Toaster
that
takes an ta"
\:.
t.
b~"
61\
int. Which
one
is called at runtime?
The
one
in Appliance. In
other
~\WI'.~~
e-t.n06
. .
words, the turnOn{int level)
can't
be
less
accessible.
That means the access level must be the same, or friendlier. That
means you can't, for example, override a public method and make
It private. What a shock that would be to the code invoking what It
thinks (at compile time) is a public method. If suddenly at runtime
the JVM slammed the door shut because the overriding version
called at runtime Is prlvatel
So far we've leamed about two
access levels: private and public.
The other two are In the deployment chapter (Release your Code)
and appendix B. There's also another rule about overriding related
to exception handling, but we'll walt until the chapter on exceptions
(Risky Behavior)
to cover thaI.
Appliance
pUblic
boolean
tumOnO
public
boolean
tumOnO
Toaster
privata
boolean
bJmOnO
\
190
Overloading
lets
you
make
multiple
versions
of
a
method,
with
different
argument
lists,
for
convenience
to
the
callers.
For
example,
if you
have a
method
that
takes only
an
int
,
the
calling
the
caller. You'll see
more
of
this
when
we
look
into
constructors
in
the
object
lifecyc1e chapter.
Since an
overloading
method
isn't
trying to
fulfill
the
polymorphism
contract
defined
by its
superc1ass,
overloaded
methods
have
much
change the return type to anything.
• You
can
vary
the
access
levels
in
any
direction.
You're free to overload a method with a method
that's more restrictive. It doesn't matter, since the
new method isn't obligated to fulfill the contract of
the overloaded method.
inheritance
and polymorphism
An
overloaded
method
is
justa
dii±erent
method
that
happens
to
have
the
sane
method
uniqueID;
public
int
addNums(int
a,
int
b)
(
return
a +
b;
public
double
addNums(double
a,
double
b)
(
return
a +
b;
public
void
setUniqueID(String
theID)
(
II
lots
of
validation
~
6i~56
b
~
Si
11
a
~
5i
65
A short Java program is listed below. One block of
the
program is missing! Yourchallenge is to match
the
candidate block of code (on
the
left),with
the
output
that
YOU'd
see if
the
block were Inserted.
Not all
the
lines of
output
wIll
be used, and some of
+
6»;
[I
args)
{
cattdldate
code
I
~
goes
here
(three
IIttes)
'
public
class
Mixed2 {
public
static
void
main(String
A a
""
new
A();
B b ;; new
B();
C c = new
e();
A a2 = new C( ) ;
output:
candidates:
c.m2();
a.m3
();
A's
ml,
A's
m2,
C's
m3,
6
c
.ml
(
);
B's
ml,
A's
m2,
A's
m3,
}
c.m2();
A's
ml,
B's
rn2,
A's
m3,
C's
mJ,
13
a2
.m2 ( ) i
a2
.m3 ( ) ;
192
chapter
7
inheritance
and
polymorphism
BE
the
Ct»mril
er
"Which
of
the
A-B
pai.rS
of
methods
listed
on
the
right,
if
inserted
{
public
static
void
maio(String
(I
args)
{
Monster
(J rna = new
Monster(3J:
ma[OI new
Vampire();
marl)
new
Dragon():
ma[2J
new
Monster():
for(iot
x =
0:
x <
3;
X++) {
ma[xJ.frighten(x);
1
e
boolean
frighten(int
iot
frighten(int
f)
{
4)
System.out.println(U
a
bite?");
return
1:
}
}
class
Vampire
extends
Monster
(
3
e
boolean
frighten(int
x)
{
System.out.println("arrrgh"):
return
false;
}
class
Dragon
extends
return
true;
}
4
e
boolean
frighten(int
z) {
System.out.println("arrrgh")i
return
true;
}
you
are
here
~
193
puzzle: Pool Puzzle
YourJob is to take code snippets from the pool and place them into
the blank lines In the code.You may use the same snippet more
than once, and you might
not
need to use all the snippets.Your
goal
Isto make a set of
classes
that will compile and run
together
as a program. Don't be fooled - this one's harder than It looks.
Pool
void
__
length::
len;
}
public
int
getLength()
{
) {
Sailboat
b2 = new
();
new Rowboat ( ) ;
b2.setLength(32);
bl.
( ) i
b3.
()i
___
.move();
}
}
public
move
()
{
public
class
Boat
Set
1will work.
Set 2 will not
compile
becauseof
Vampire's
retum
type
(Int).
The
Vampire's
frightenO
method
(B)is not a legal
override OR
overload
of Monster's
frightenO
method.
Changing
ONLYthe retumtype Isnot
enough
to makea valid
overload,
and sincean int is not
compatible with a
boolean.
the
method
is not a valid
Vampire's
set 4 takes a byte,
not
an lnr.)
Mixed
MessagES
B's
ml,
B's
ml,
A'8
ml,
A's
m2,
C's
m3,
6
A's
mz
,
A'9
m3,
B'B
m2,
A's
m3,
A's
mz
,
C's
rowTheBoat()
{
System.out.print("stroke
natasha")1
public
class
Boat
{
private
int
length
public
void
setLength
(
int
len ) {
length
=
lenl
public
int
getLength()
return
length
1
pub.l.Lc void move ( )
System.
out.
print
1
b2
.move()
1
pub
Li.c
class
Sailboat
extends
Boat
{
public
void mover i {
System.out.print(
"hoist
sail
••
) 1
196
chapter
7
OUTPUT:
drift drift
hoist
sail
this is a new chapter
197
8 interfaces and abstract classes
Inheritance is just the beginning.
4OEXPLOITPOLYMORPHISMWENEEDINTERFACES
picture
food
prey
Cat
size
picture
food
prey
Wolf
size
picture
food
prey
Dog
size
picture
food
prey
Hippo
makeNoise()
eat()
roam()
makeNoise()
eat()
makeNoise()
eat()
makeNoise()
eat()
makeNoise()
eat()
you are here4
199
Wolf aWolf = new Wolf();
We know we can say:
A Wolf reference to a
Wolf object.
Wolf
aWolf
W
o
l
f
o
b
j
e
c
t
These two are the same type.
Animal aHippo = new Hippo();
And we know we can say:
Animal reference to
a Hippo object.
Animal
aHippo
H
i
t
These two are the same type, but
what the heck does an Animal object look like?
?
200
chapter 8
scary objects
What does a new Animal() object
look
like?
when objects go bad
)TMAKESSENSETOCREATEA7OLFOBJECTORA(IPPO
OBJECTORA4IGEROBJECTBUTWHATEXACTLYISAN
!NIMALOBJECT7HATSHAPEISIT7HATCOLORSIZE
NUMBEROFLEGS
4RYINGTOCREATEANOBJECTOFTYPE!NIMALISLIKEA
NIGHTMARE3TAR4REK©TRANSPORTERACCIDENT4HE
ONEWHERESOMEWHEREINTHEBEAMMEUPPROCESS
SOMETHINGBADHAPPENEDTOTHEBUFFER
"UTHOWDOWEDEALWITHTHIS7ENEEDAN!NIMAL
CLASSFORINHERITANCEANDPOLYMORPHISM"UTWE
WANTPROGRAMMERSTOINSTANTIATEONLYTHELESS
ABSTRACTSUBCLASSESOFCLASS!NIMALNOT!NIMALITSELF
7EWANT4IGEROBJECTSAND,IONOBJECTSNOT!NIMAL
OBJECTS
&ORTUNATELYTHERESASIMPLEWAYTOPREVENTACLASS
FROMEVERBEINGINSTANTIATED)NOTHERWORDSTOSTOP
ANYONEFROMSAYINGhnewvONTHATTYPE"YMARKING
THECLASSASabstractTHECOMPILERWILLSTOPANY
DECLAREDREFERENCETYPEFORTHEPURPOSEOFPOLYMORPHISMBUT
YOUDONTHAVETOWORRYABOUTSOMEBODYMAKINGOBJECTSOFTHAT
TYPE4HECOMPILERGUARANTEESIT
abstract public class Canine extends Animal
{
public void roam() { }
}
public class MakeCanine {
public void go() {
Canine c;
c = new Dog();
c = new Canine();
c.roam();
}
}
File Edit Window Help BeamMeUp
% javac MakeCanine.java
MakeCanine.java:5: Canine is abstract;
cannot be instantiated
c = new Canine();
^
1 error
class Canine is marked abstract,
so the compiler will NOT let you do this.
An abstract class has virtually* no use, no value, no
purpose in life, unless it is
extended
.
With an abstract class, the guys doing the work at runtime
CONCRETESUBCLASSOF#OMPONENTBUT
NEVER#OMPONENTITSELF
Tiger
Animal
Canine
abstract
abstract
abstract
Hippo
concrete
Dog
Wolf
concrete
Cat
Lion
concrete
Hmmmm do I
feel like red or
white tonight?
Hmmmm the Camelot
Vineyards 1997 Pinot
Noir was a pretty
decent year
(OWDOYOUKNOWWHENACLASSSHOULDBE
ABSTRACT7INEISPROBABLYABSTRACT"UTWHAT
ABOUT2EDAND7HITE!GAINPROBABLYABSTRACT
FORSOMEOFUSANYWAY"UTATWHATPOINTINTHE
HIERARCHYDOTHINGSBECOMECONCRETE
$OYOUMAKE0INOT.OIRCONCRETEORISITABSTRACT
TOO)TLOOKSLIKETHE#AMELOT6INEYARDS
SENSEINTHEABSTRACTMETHODYOUWONTPUTINAMETHODBODY3ONO
CURLYBRACESJUSTENDTHEDECLARATIONWITHASEMICOLON
public abstract void eat();
No method body!
End it with a semicolon.
If you declare an abstract
method
, you MUST
mark the
class
abstract as well. You can’t have
an abstract method in a non-abstract class.
)FYOUPUTEVENASINGLEABSTRACTMETHODINACLASSYOUHAVETO
MAKETHECLASSABSTRACT"UTYOUCANMIXBOTHABSTRACTANDNON
ABSTRACTMETHODSINTHEABSTRACTCLASS
Q: 7HATISTHEPOINTOFANABSTRACTMETHOD)THOUGHT
THEWHOLEPOINTOFANABSTRACTCLASSWASTOHAVECOMMON
CODETHATCOULDBEINHERITEDBYSUBCLASSES
A: )NHERITABLEMETHODIMPLEMENTATIONSINOTHERWORDS
METHODSWITHACTUALBODIESARE!'OOD4HINGTOPUTINA
SUPERCLASS7HENITMAKESSENSE!NDINANABSTRACTCLASSIT
OFTENDOESNTMAKESENSEBECAUSEYOUCANTCOMEUPWITH
ANYGENERICCODETHATSUBCLASSESWOULDFINDUSEFUL4HE
POINTOFANABSTRACTMETHODISTHATEVENTHOUGHYOUHAVENT
PUTINANYACTUALMETHODCODEYOUVESTILLDEFINEDPARTOF
THEPROTOCOLFORAGROUPOFSUBTYPESSUBCLASSES
Q: 7HICHISGOODBECAUSE
A: 0OLYMORPHISM2EMEMBERWHATYOUWANTISTHE
ABILITYTOUSEASUPERCLASSTYPEOFTENABSTRACTASAMETHOD
ARGUMENTRETURNTYPEORARRAYTYPE4HATWAYYOUGETTO
METHODSFROM!NIMAL$OGHASTOIMPLEMENTALLOF!NIMALSABSTRACTMETHODS
Implementing
an abstract
method is just like
overriding
a method.
7HENWESAYhYOUMUSTIMPLEMENTTHEABSTRACTMETHODvTHATMEANSYOUMUST
PROVIDEABODY4HATMEANSYOUMUSTCREATEANONABSTRACTMETHODINYOURCLASS
WITHTHESAMEMETHODSIGNATURENAMEANDARGUMENTSANDARETURNTYPETHATIS
COMPATIBLEWITHTHEDECLAREDRETURNTYPEOFTHEABSTRACTMETHOD7HATYOUPUTIN
THATMETHODISUPTOYOU!LL*AVACARESABOUTISTHATTHEMETHODISTHEREINYOUR
CONCRETESUBCLASS
I have wonderful news,
mother. Joe finally implemented
all his abstract methods! Now
everything is working just the
way we planned
interfaces and polymorphism
you are here4
205
Sharpen your pencil
,ETSPUTALLTHISABSTRACTRHETORICINTOSOMECONCRETEUSE)NTHEMIDDLE
COLUMNWEVELISTEDSOMECLASSES9OURJOBISTOIMAGINEAPPLICATIONS
WHERETHELISTEDCLASSMIGHTBECONCRETEANDAPPLICATIONSWHERETHELISTED
CLASSMIGHTBEABSTRACT7ETOOKASHOTATTHElRSTFEWTOGETYOUGOING
&OREXAMPLECLASS4REEWOULDBEABSTRACTINATREENURSERYPROGRAMWHERE
DIFFERENCESBETWEENAN/AKANDAN!SPENMATTER"UTINAGOLFSIMULATION
PROGRAM4REEMIGHTBEACONCRETECLASSPERHAPSASUBCLASSOF/BSTACLE
BECAUSETHEPROGRAMDOESNTCAREABOUTORDISTINGUISHBETWEENDIFFERENT
TYPESOFTREES4HERESNOONERIGHTANSWERITDEPENDSONYOURDESIGN
private int nextIndex = 0;
public void add(Dog d) {
if (nextIndex < dogs.length) {
dogs[nextIndex] = d;
System.out.println(“Dog added at “ + nextIndex);
nextIndex++;
}
}
}
MyDogList
Dog[] dogs
int nextIndex
add(Dog d)
Use a plain old Dog array
behind the scenes.
We’ll increment this each
time a new Dog is added.
If we’re not already at the limit
of the dogs array, add the Dog
and print a message.
increment, to give us the
next index to use
Building our own Dog-specifi c list
(Perhaps the world’s worst attempt at making our
own ArrayList kind of class, from scratch.)
V
E
R
S
O
N
2
Uh-oh, now we need to keep Cats, too.
7EHAVEAFEWOPTIONSHERE
-AKEASEPARATECLASS-Y#AT,ISTTOHOLD#ATOBJECTS0RETTYCLUNKY
-AKEASINGLECLASS$OG!ND#AT,ISTTHATKEEPSTWODIFFERENTARRAYSASINSTANCE
VARIABLESANDHASTWODIFFERENTADDMETHODSADD#AT#ATCANDADD$OG$OG
D!NOTHERCLUNKYSOLUTION
-AKEHETEROGENEOUS!NIMAL,ISTCLASSTHATTAKESANYKINDOF!NIMALSUBCLASS
SINCEWEKNOWTHATIFTHESPECCHANGEDTOADD#ATSSOONERORLATERWELLHAVE
SOMEOTHERKINDOFANIMALADDEDASWELL7ELIKETHISOPTIONBESTSOLETSCHANGE
OURCLASSTOMAKEITMOREGENERICTOTAKE!NIMALSINSTEADOFJUST$OGS7EVE
HIGHLIGHTEDTHEKEYCHANGESTHELOGICISTHESAMEOFCOURSEBUTTHETYPEHAS
CHANGEDFROM$OGTO!NIMALEVER
YWHEREINTHECODE
public class AnimalTestDrive{
public static void main (String[] args) {
MyAnimalList list = new MyAnimalList();
Dog a = new Dog();
Cat c = new Cat();
list.add(a);
list.add(c);
}
}
File Edit Window Help Harm
% java AnimalTestDrive
Animal added at 0
Animal added at 1
3
What about non-Animals? Why not make
a class generic enough to take anything?
Many of the ArrayList methods use the
ultimate polymorphic type, Object. Since
every class in Java is a subclass of Object,
these ArrayList methods can take anything!
(Note: as of Java 5.0, the get() and add()
methods actually look a little different
than the ones shown here, but for now this
is the way to think about it. We’ll get into
the full story a little later.)
the ultimate superclass: Object
!RRAY,IST
(These are just a few of the
methods in ArrayList there
are many more.)
%VENIFYOUTAKEADVANTAGEOFPOLYMORPHISM
YOUSTILLHAVETOCREATEACLASSWITHMETHODS
THATTAKEANDRETURNYOURPOLYMORPHICTYPE
7ITHOUTACOMMONSUPERCLASSFOREVERYTHING
IN*AVATHEREDBENOWAYFORTHEDEVELOPERS
OF*AVATOCREATECLASSESWITHMETHODSTHAT
COULDTAKEYOURCUSTOMTYPESTYPESTHEYNEVER
KNEWABOUTWHENTHEYWROTETHE!RRAY,ISTCLASS
3OYOUWEREMAKINGSUBCLASSESOFCLASS/BJECT
FROMTHEVERYBEGINNINGANDYOUDIDNTEVEN
KNOWIT%VERYCLASSYOUWRITEEXTENDS/BJECT
WITHOUTYOUREVERHAVINGTOSAYIT"UTYOUCAN
THINKOFITASTHOUGHACLASSYOUWRITELOOKSLIKE
interfaces and polymorphism
you are here4
209
So what’s in this ultra-super-megaclass Object?
Object
boolean equals()
Class getClass()
int hashCode()
String toString()
)FYOUWERE*AVAWHATBEHAVIORWOULDYOUWANTEVERY
OBJECTTOHAVE(MMMMLETSSEEHOWABOUTA
METHODTHATLETSYOUlNDOUTIFONEOBJECTISEQUAL
TOANOTHEROBJECT7HATABOUTAMETHODTHATCAN
TELLYOUTHEACTUALCLASSTYPEOFTHATOBJECT-AYBEA
METHODTHATGIVESYOUAHASHCODEFORTHEOBJECTSO
YOUCANUSETHEOBJECTINHASHTABLESWELLTALKABOUT
*AVASHASHTABLESINCHAPTERANDAPPENDIX"
/HHERESAGOODONEAMETHODTHATPRINTSOUTA
3TRINGMESSAGEFORTHATOBJECT
!NDWHATDOYOUKNOW!SIFBYMAGICCLASS/BJECT
DOESINDEEDHAVEMETHODSFORTHOSEFOURTHINGS
4HATSNOTALLTHOUGHBUTTHESEARETHEONESWE
REALLYCAREABOUT
Just SOME of the methods
of class Object.
Dog a = new Dog();
Cat c = new Cat();
if (a.equals(c)) {
System.out.println(“true”);
for the object (for
now, think of it as a
unique ID).
Tells you if two objects are
considered ‘equal’ (we’ll talk
about what ‘equal’ really
means in appendix B).
Gives you back the
class that object was
instantiated from.
Prints out a String message
with the name of the class
and some other number we
rarely care about.
YourClassHere
Every class you write inherits all the
methods of class Object. The classes
you’ve written inherited methods you
didn’t even know you had.