320 likes | 464 Views
Inheritance in Java. Behind the scenes: new Objects from old. Review: MileMover. public class MileMover extends UrRobot{ public MileMover(int st, int ave, Direction dir, int beepers) { super(st, ave, dir, beepers); } public void moveMile() {
E N D
Inheritance in Java Behind the scenes: new Objects from old
Review: MileMover public class MileMover extends UrRobot{ public MileMover(int st, int ave, Direction dir, int beepers) { super(st, ave, dir, beepers); } public void moveMile() { move(); move(); move(); move(); move(); move(); move(); move(); } }
Class Name UrRobot move()turnLeft()pickBeeper()putBeeper()turnOff() Public Methods MileMover: UML Diagrams
MileMover extends UrRobot moveMile() MileMover: UML Diagrams UrRobot move()turnLeft()pickBeeper()putBeeper()turnOff()
UrRobot turnLeft()pickBeeper()putBeeper()move()turnOff() MileMover extends UrRobot moveMile() Tracing method calls MileMover foo = new MileMover(1,1,East,5); foo.moveMile(); foo.move(); • For every method called on an instance… • Check the definition of the class the object was constructed as… • If method not found, check the super class • If method not found, check the super super class • Etc.
Change MileMover… This is called “overiding” the move method. To access original move method: make explicit call to parent class using super.method() What would happen if we left it as move() ? public class MileMover extends UrRobot{ public MileMover(int st, int ave, Direction dir, int beepers) { super(st, ave, dir, beepers); } public void moveMile() { move(); move(); move(); move(); move(); move(); move(); move(); } } public void move() super.move(); super.move(); super.move(); super.move(); super.move(); super.move(); super.move(); super.move();
MileMover extends UrRobot move()2 What now?… MileMover foo = new MileMover(1,1,East,5); foo.move(); UrRobot turnLeft()pickBeeper()putBeeper()move()1turnOff() Which one does it use?
Inheritance: a different view Think of it this way: new class is constructed on the fly based on the definitions available starting at the bottom. UrRobot turnLeft() pickBeeper() putBeeper() move()1 turnOff() MileMover foo = new MileMover(1,1,East,5); MileMover extends UrRobot move()2 turnLeft() pickBeeper() putBeeper() turnOff() foo MileMover extends UrRobot move()2
How to use this advantageously… • Baker: go to BlueJ
Toward Polymorphism • Poly-morph-ism • Overriding methods is not polymorphism in and of itself - but it is a big part of it • REMEMBER: Each instance interprets a method call in terms of how it was instantiated…
…A Quick Step Back - Object references • Let’s do original harvesting task with teams of robots -- have 3 robots harvest 2 rows each. HarvesterBot one = new HarvesterBot(2,2,…); HarvesterBot two = new HarvesterBot(4,2,…); HarvesterBot three = new HarvesterBot(6,2,…); one.move(); one.harvestTwoRows(); two.move(); two.harvestTwoRows(); three.move(); three.harvestTwoRows();
…A Quick Step Back - Object references • Could also intersperse operations like this: one.move(); two.move(); three.move(); one.harvestTwoRows(); two.harvestTwoRows(); three.harvestTwoRows();
…A Quick Step Back - Object references • How about this? HarvesterBot one; one = new HarvesterBot(2,2,…); one.move(); one.harvestTwoRows(); one = new HarvesterBot(4,2,…); one.move(); one.harvestTwoRows(); one = new HarvesterBot(6,2,…); one.move(); one.harvestTwoRows(); a reference to a HarvesterBot 3 instantiations
Object References CODE Memory HarversterBot one; one = new HarversterBot(2,2,…) one = new HarversterBot(4,2,…) one = new HarversterBot(6,2,…) Garbage (no more references to these things) HarvesterBot Street : 2 Avenue : 2 one HarvesterBot Street : 4 Avenue : 2 NOTE: “one” gets re-assigned to point to different, new objects. The old objects, which no longer have a reference to them, are forgotten about and collected as “garbage.” HarvesterBot Street : 6 Avenue : 2
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…
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…
Remember the Big Picture • MileWalker and Harvester extend UrRobot. They are UrRobots. UrRobot MileWalker DropBeeperAndWalker BackwardWalker
MileWalker -- definition public class MileWalker extends UrRobot { // constructor same as always public void move() { super.move(); super.move(); super.move(); super.move(); super.move(); super.move(); super.move(); super.move(); } }
DropBeeperAndWalker -- DefN public class DropBeeperAndWalker extends UrRobot { // constructor same as always public void move() { putBeeper(); //inherited super.move(); } }
BackwardWalker -- definition • 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…
Sample Driver -- mine vs. yours 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! UrRobot bot; bot = new MileWalker(…); bot.move(); // polymorphic move() bot = new DropBeeperAndWalker(…); bot.move(); // polymorphic move() bot = new BackwardWalker(…); bot.move(); // polymorphic move()
…now Polymorphism • Because these types extend UrRobot they all ARE UrRobots. So these instantiations are legal… UrRobot soren = new UrRobot(…) UrRobot mark = new MileMover(…) UrRobot rebecca = new Harvester(…)
Polymorphism UrRobot soren = new UrRobot(…) UrRobot mark = new MileMover(…) UrRobot rebecca = new Harvester(…) An object 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!
Polymorphism UrRobot soren = new UrRobot(…) UrRobot mark = new MileMover(…) UrRobot rebecca = new Harvester(…) rebecca.move(); So, this is a legal call to move() since java can ensure a move method exists somewhere as part of rebecca.
Polymorphism UrRobot soren = new UrRobot(…) UrRobot mark = new MileMover(…) UrRobot rebecca = new Harvester(…) rebecca.move(); rebecca.harvestSixRows(); THIS IS NOT legal. Why? Because java cannot ensure that harvestSixRows exists. Why? Because rebecca was declared as a UrRobot.
Compile Time vs. Run Time • At time of compilation only superficial syntax checking is done. Compiler does not inspect the objects. • At Run Time the objects are actually constructed.
Compile Time vs. Run Time • So Think of things from the compiler’s perspective: • UrRobot rebecca = new Harvester(…) Ok, because Harvester extends UrRobot • rebecca.move(); Ok, because rebecca is of type UrRobot and UrRobot has a move() method. • rebecca.harvestSixRows();NOT OK -- THIS WILL NOT COMPILE because as far as the compiler knows rebecca is a UrRobot (declared as such) and UrRobot does not have harvestSixRows().
How is this helpful? • Collections of robots that we can set to work regardless of what type they are. • This is very helpful for generic programming. • Allows class design to be flexible
UrRobot turnLeft() pickBeeper() putBeeper() move() turnOff() MileMover extends UrRobot move() Recap: Polymorphism Now what happens? UrRobot mark = new MileMover(1,1,East,5); mark.move(); Which move() method does mark use? Mark will use the definition of move from MileMover. Why? Because mark was constructed as a MileMover.
Polymorphism Remember how this will be constructed at run-time… UrRobot turnLeft() pickBeeper() putBeeper() move()1 turnOff() UrRobot mark = new MileMover(1,1,East,5); MileMover extends UrRobot move()2 turnLeft() pickBeeper() putBeeper() turnOff() mark MileMover extends UrRobot move()2
Blow your mind UrRobot turnLeft() pickBeeper() putBeeper() move() turnOff() MileMover extends UrRobot moveMile(){ move();move();move();move(); } MileTurner extends MileMover move(){ turnLeft(); super.move(); }
Polymorphism • “It is the robot itself, not the name by which we refer to it, that determines what is done when a message is received.” --Bergin p. 70 • “It will act like the class it was constructed as not necessarily as the class it was declaredas.” --Franke