Visiting Avatar

advertisement
Comp 401 – Assignment 9:
Abstract Methods and Visiting Avatar
Date Assigned: Wed Oct 27, 2010
Completion Date: Fri Nov 5, 2010
Early Submission Date: Wed Nov 3, 2010
In this assignment you will gain experience with abstract method. In case you did not use
instanceof in the parser of assignment 8, you will do so now. You will also do recursive descent
parsing. In addition, you will extend your Halloween simulation to determine if an avatar is
visiting a house
House Visit by Avatar
Extend your house with a new boolean function that takes as an argument an avatar, and
returns true if the feet of the avatar (bottom point of the leg line) are in the path of the house.
You can add this method to a new class that builds on the house classes from before, or simply
change some previous house class that defines a path. You have defined several versions of
avatars (avatar, avatar with candies) – the method can take as an argument any one of the
various versions of the avatar that is sufficient to determine the location of an avatar’s feet. For
instance it can accept avatar with candies but not avatar. As the function takes an avatar as an
argument, it does not define a property of a house. It takes as an argument an avatar. The
function is independent of whether the house is part of a simulation. To demonstrate it works,
thus, you don’t have to even create a full simulation. As the function takes a complex object as
an argument, it is not convenient to use ObjectEditor to interactively call it.
Simulation Extension
To test the Boolean function above, modify your simulation to include a single-parameter public
method that determines if the avatar in the simulation is in the path of a particular house in the
house list, where the index of the house is given by the parameter of the method. To modify
the simulation, you don’t have to create subtypes, you can simply edit the current class and
interface of the simulation.
Combining Stick Avatar and Mailbox with Abstract Methods
The stick avatar and mailbox that are identical except that one has an oval and another has a
rectangle. Use abstract methods to share the common code in these two classes. This means
you must create a new abstract class for the common code that declares one or more abstract
methods implemented by the avatar and mailbox classes.
Ideally the concrete subclasses will have no getter methods. Moreover the abstract super class
should have no knowledge of an oval or a rectangle, nor should it receive this shape as a
constructor parameter.
It is possible that your current avatar and mailbox classes inherit from different classes . Java
does not support multiple class inheritance - as the two classes now inherit from a common
super-class, you may have to duplicate some inherited code in the classes to meet the constraint
of the assignment. This is a common problem and solution in Java.
Java does allow multiple inheritance of interfaces. So this change does not require you to
change any interface or constructor implemented by the current classes. You may, however,
have to rename methods in the original interfaces and even the order of the parameters of
these methods. This change may result in the two interfaces being combined into one. You
may, thus, have to change the code that uses the original interfaces.
One way to avoid making these tedious changes is to rename the methods in the original
interfaces before you create the new interfaces. The Eclipse Refactor-Rename command can be
used to do so automatically – it changes all references to the renamed method. Also you can
create empty extensions of a common interface to retain the original interface names. If you
don’t understand this paragraph, simply make the changes manually.
Recursive-Descent Parsing
Process each of the user commands you support so far in a separate method – that is, use
recursive-descent parsing.
Mapping multiple words to a single user command
In assignment 7, you created a separate token class for each of the commands: move, take, give,
addHouse, removeHouse, animate, undo, and redo. It was not clear what you benefitted from
doing so as it was possible to create a single class for all of these tokens and use the toString()
and equals() method, instead of instanceof, to distinguish between them. One reason for
creating a separate token class is efficiency – instanceof is faster than equals(). If we must
determine multiple times if a word is a particular user command, it is overall more efficient to
use instanceof. A more compelling reason is information hiding and extensibility. The parser
should not know the mapping between words and user commands. Thus, you can change this
mapping by changing only the scanner.
To demonstrate this extensibility, change the scanner of assignment 7 to map at least two words
to one of the token classes. For instance, map both the words mv and move to the token class
you created for the word move. As a result, the user can now enter:
move 50 50
or
mv 50 50
to move an avatar 50 units in the x and y direction. These changes should require no change to
the parser class. If your assignment 8 is implemented properly using instanceof, and you
implemented the first extra credit feature of that assignment, then this part will require no extra
work.
It is up to you to determine which command you map to multiple words, and what the
additional word is.
Submission Instructions
As always, submit to blackboard your code together with screenshots of test cases.
Download