Object References a.k.a. variables

advertisement
Object References
a.k.a. variables
• Teams of Robots (e.g.)
– Could have 1 robot harvest 6 rows (we’ve seen that)
– Could have 3 robots each harvest 2 rows like this:
Harvester botA = new Harvester(2,2,…,…);
Harvester botB = new Harvester(4,2,…,…);
Harvester botC = new Harvester(6,2,…,…);
botA.move(); botA.harvestTwoRows();
botB.move(); botB.harvestTwoRows();
botC.move(); botC.harvestTwoRows();
Ch. 4.1 - 4.3
1
Object References
• Could also intersperse the operations like this:
// same instantiations
botA.move();
botB.move();
botC.move();
botA.harvestTwoRows();
botB.harvestTwoRows();
botC.harvestTwoRows();
Ch. 4.1 - 4.3
2
Object References
• Could just use one reference
like this:
Harvester bot;
bot = new Harvester(2,2,…,…);
bot.move();
bot.harvestTwoRows();
bot = new Harvester(4,2,…,…);
bot.move();
bot.harvestTwoRows();
bot = new Harvester(6,2,…,…);
bot.move();
bot.harvestTwoRows();
Ch. 4.1 - 4.3
a reference
instantiating 3 objects
we use assignment to
assign a specific
object to a reference
3
Object References - Common Error
• Harvester bob;
bob.harvestTwoRows();
• What’s wrong with the above?
• NullPointerException
– for now, an error in Java is called an exception
– do you think this error happens at run-time or
compile-time? why?
• Binky Pointer Video
(instructors: you can find it and other neat cs videos/materials at http://cslibrary.stanford.edu you’ll want to download ahead of time, as it is huge)
Ch. 4.1 - 4.3
4
Object References
• References model what’s going on in the real world
as well
– There are lots of “Dave” references - but the
particular object (person) one is referring to
depends on context and whom one is, in
particular, referring to at the moment
– Well, these references are all neat and everything,
but so what? Well, hold on a few more slides and
you’ll see the power of using them - we’re headed
toward an extremely important OO concept called
Polymorphism.
Ch. 4.1 - 4.3
5
Polymorphism
• Powerful example:
– you are all objects - if I tell all of you to “takeABreak()”,
you all will hear the same message but will act in
different ways (some of you will sleep, some will walk out the
door and eat something, some will try to leave school!, some will
do work, etc.) - that’s polymorphism
• sending the same message to different objects - each
individual object has a particular way to interpret
(implement) the message
• so, back to code and a Java/Karel example…
Ch. 4.1 - 4.3
6
Overriding move()
• remember MileWalker?
– we named its one method moveMile()
– we could have named the method move() and then
redefined what “move” means to a MileWalker. Again,
we’re modeling the real world. The concept of “move” is
different depending on what type of object is “moving”
(think about how a dog, fish, bird, etc., “move”)
– so, since the general concept is the same, we often use
the same name (it makes coding easy/logical) - why
would you want to try to remember moveMile(),
moveLegs(), moveWings(), etc. - why not just one
identifier for that - move()
Ch. 4.1 - 4.3
7
Example
• let’s have 3 different types of bots
– MileWalker
• when move() is invoked, moves 1 mile
– DropBeeperAndWalker
• when move() is invoked, always drops a beeper and then moves one block
forward
– BackwardWalker (sort of the Michael Jackson of robots!)
• when move() is invoked, moves one block backward
• for each of these new classes, we will only have to write one
method, move() - each, however, will be implemented
differently, and, in addition, override the original definition
of move() inherited from UrRobot --- let’s see…
Ch. 4.1 - 4.3
8
As always, the Big Picture first
a.k.a. - Inheritance Hierarchy
UrRobot
MileWalker
DropBeeperAndWalker
BackwardWalker
Ch. 4.1 - 4.3
9
MileWalker
public class MileWalker extends UrRobot
{
heading needs to
// constructor same as always
public void move() {
super.move(); super.move();
be identical to the
one in the API for
UrRobot in order
for “overriding” to
work
super.move(); super.move();
super.move(); super.move();
super.move(); super.move();
}
}
Ch. 4.1 - 4.3
10
DropBeeperAndWalker
public class DropBeeperAndWalker extends UrRobot
{
// constructor same as always
public void move() {
putBeeper(); // inherited instruction still serves its purpose
super.move();
}
class invariant: object always
}
has at least one beeper for each
time move() might be called
(AB topic)
Ch. 4.1 - 4.3
11
BackwardWalker
• You write it!
• In addition to writing this class, write a sample
Driver that would demonstrate using one robot each
of type MileWalker, DropBeeperAndWalker, and
BackwardWalker
– We’ll pick someone and put it up in 5 minutes…
Ch. 4.1 - 4.3
12
Your sample Driver vs. mine
UrRobot bot;
bot = new MileWalker(…);
bot.move();
// polymorphic move()
bot = new DropBeeperAndWalker(…);
bot.move();
// polymorphic move()
bot = new BackwardWalker(…);
bot.move();
// polymorphic move()
Ch. 4.1 - 4.3
a reference can
refer to any
object as long
as the object is
of the same
type or a type
of one of its
subclasses
somewhere
down the
Inheritance
tree!
13
Polymorphism
• at run-time, the correct implementation is chosen
depending on what specific object is being
referenced at that moment in time.
bot
then later…
then yet even later…
instance of
instance of
instance of
MileWalker DropBeeperAndWalkerBackwardWalker
Ch. 4.1 - 4.3
14
Polymorphism - cont’d
• polymorphism is ubiquitous in OO
• there are many uses and examples of it
• let’s now build toward another example of
polymorphism
– but first, as last time, we need some setup…
Ch. 4.1 - 4.3
15
Choreographers
• one object controlling others
• we now want a MoveChoreographer class, which, when
constructed, is passed 3 friends (robots)
• the MoveChoreographer has one method called,
moveFriends() which, when invoked, “moves” each friend
once
• this Choreographer model of problem solving, by the way,
can been seen in the “general contractor” analogy we used
in the ppt from Ch. 3 - the general contractor doesn’t really
do the work, she just delegates it to another object(s)
Ch. 4.1 - 4.3
16
MoveChoreographer
public class MoveChoreographer extends UrRobot
{
// constructor on next slide
// other methods
private UrRobot delegateA;
private UrRobot delegateB;
private UrRobot delegateC;
objects can not
only do(behavior)
things, they can
also
remember(state)
things
instance variables
}
Ch. 4.1 - 4.3
17
MoveChoreographer’s constructor
public MoveChoreographer (
int st, int av,
Direction dir, int numBeepers,
UrRobot botA,
UrRobot botB,
UrRobot botC )
{
super (st, av, dir, numBeepers);
delegateA = botA;
delegateB = botB;
delegateC = botC;
// must come first in method
instance variables
being assigned
}
Ch. 4.1 - 4.3
18
MoveChoreographer’s
moveFriends()
public void moveFriends()
{
delegateA.move();
delegateB.move();
delegateC.move();
}
Ch. 4.1 - 4.3
19
Sample Client code using a
MoveChoreographer
• can you now give some sample client code that uses
a MoveChoreographer object? (do so now for 5
minutes…)
draw a picture and
an example:
UrRobot bot1 = new MileWalker(2, 4, North, 0) ;
show the before and
after
UrRobot bot2 = new DropBeeperAndWalker(2, 5, North, infinity);
UrRobot bot3 = new BetterTurner(2, 6, North, 0);
MoveChoreographer chor;
chor = new MoveChoreographer(1, 1, North, 0, bot1, bot2, bot3);
chor.moveFriends();
Ch. 4.1 - 4.3
20
examining the constructor’s
reference types
The statement from the previous slide,
chor = new MoveChoreographer(1, 1, North, 0, bot1, bot2, bot3);
is kind of neat. When someone constructs a
MoveChoreographer, he can pass any 3 robots in any order as
long as each one is-A UrRobot or extends from a UrRobot.
The MoveChoreographer only wants to be guaranteed that it
can perform a move() on any object passed to it - since there is
a move() in UrRobot, it chose to make its parameters of type
UrRobot, guaranteeing (to itself and the compiler) that it will be able
to call move() at run-time.The term that describes which
particular move() will be called at run-time is ____________?
Ch. 4.1 - 4.3
21
Abstract classes
• Sometimes we want to do several tasks, but the tasks
are very similar. How can we build the classes to
take advantage of the common parts of the task and
yet distinguish the specific differences? Another
way to say that is, how can we design the
inheritance tree so that we don’t duplicate common
code used among sub-classes, yet allow sub-classes
to have some specific differences?
• The answer = use an abstract class…
Ch. 4.1 - 4.3
22
contrived/simple task to demo the
need for an abstract class run demo
Here is a task for a team of robots. We want to lay
down beepers in a 5-by-4 field. The odd-numbered
rows have 2 beepers per corner, the even have 3. Here
is how we’d organize that with what we currently
know:
discuss problems with
UrRobot
design
TwoRowLayer
ThreeRowLayer
layBeepers()
layBeepers()
putBeepers()
putBeepers()
Ch. 4.1 - 4.3
23
BeeperLayers
On the previous slide, we saw that layBeepers() would
have the exact same implementation for both types
of beeper layers - namely:
discuss why code
{
duplication (a.k.a.,
move();
putBeepers();
copy/paste) and lack
move();
putBeepers();
of localization are
poor/costly design
move();
putBeepers();
patterns
move();
putBeepers();
move();
}
Ch. 4.1 - 4.3
24
BeeperLayers
At the same time, we saw that putBeepers() would have a
different implementation in each of the subclasses (one puts 2,
the other puts 3). So here is the new design pattern:
We’ll extract out an abstract concept of what a general beeper
layer would look like and put that into a class(in this case, an
abstract class). Methods in the abstract class that would have
the exact same implementation regardless of the subclass will
be implemented in the abstract class - methods that would
have different implementations in the subclasses will not be
implemented in the abstract class, forcing each subclass to
give its own unique implementation…
25
Ch. 4.1 - 4.3
Inheritance Hierarchy
UrRobot
BeeperLayer
public void layBeepers() { … }
public abstract void putBeepers();
TwoRowLayer
ThreeRowLayer
public void putBeepers() { … }
Ch. 4.1 - 4.3
public void putBeepers() { … }
26
Terminology & Concepts
BeeperLayer lisa = null;
lisa = new TwoRowLayer(1, 3 ,East, infinity);
lisa.layBeepers();
lisa = new ThreeRowLayer(2, 3, East, infinity);
lisa.layBeepers();
lisa = new TwoRowLayer(3, 3, East, infinity);
lisa.layBeepers();
lisa = new ThreeRowLayer(4, 3, East, infinity);
lisa.layBeepers();
lisa = new TwoRowLayer(5, 3, East, infinity);
lisa.layBeepers();
making references to the
code, the inheritance
tree, or whatever else we
just discussed in the
BeeperLayer problem,
pick one of these terms
and demonstrate that you
know what it means
abstraction, abstract class, abstract method, polymorphism
Ch. 4.1 - 4.3
27
Download