![]() |
![]() |
|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
In explore, we had a big huge if-else statement. If we wanted hundreds of commands, this would get unwieldy. And also there is a maintenence issue: when adding a new command, we'd like to make sure it gets mentioned in the "help" information.
One initial wish might be “I want a List of commands -- that is, a List that contains bare functions.” Java doesn't allow this, but with inheritance we can get close: we can make a class GrueCommand
class LookCommand { String commandName = "look"; /** Have the given explorer perform this 'look' task. * @param e The Explorer to perform the 'look' task. */ String perform(Explorer e) { Room here = e.getCurrentRoom(); // all the code involved in looking around: return "You are in " + here.getName() + "\n" + "You see " + here.getLoot().toString() + "\n" + The exits are " + here.getNeighbors().toString() + "\n"; } } class GrabCommand { String commandName = "grab"; /** Have the given explorer perform this 'grab' task. * @param e The Explorer to perform the 'grab' task. */ String perform(Explorer e) { int treasureIndex = io.promptForInt( "What do you want to pick up? " ); if (treasureIndex == TextIO.NO_SELECTION_MADE) { io.display( "You change your mind." ); } else { java.util.List<Treasure> localLoot = e.getCurrentRoom().getLoot(); Treasure t = localLoot.get(treasureIndex); io.display( e.grab(t) ); } } } |
We'd like to have these commands all in a list, so our explore method becomes:
for ( c : allCommands ) { if (request.equals(c.getCommandName())) { c.perform(this); } } |
But we have a problem -- we need each of the above classes to be part of a single class (so that we can name a type for c), and yet we needed them to be in different classes so that we could actually have different code for each perform method.
Solution? Inheritance:
abstract class Command { String commandName; /** Have the given explorer perform some specific task. * @param e The Explorer to perform the specific task. */ abstract String perform(Explorer e); } class LookCommand extends Command { &hellp; } class GrabCommand extends Command { &hellp; } |
java.util.List<Command> allCommands = new java.util.LinkedList<Command>(); allCommands.add( new LookCommand() ); allCommands.add( new GrabCommand() ); // etc. |
(Note that if Java allowed us to pass methods as inputs, this wouldn't have been a difficult problem. In fact, in many languages this is allowed; in those languages “functions are first-class values”, meaning they can be passed to and from methods just like any other value.)
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Dec.03 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |
![]() |