Assignment 1: Writing, Changing, and Debugging a Java Program

Comp 114, Fall 2005
Assignment 3: Inheritance Galore!
Date Assigned: Tue Sep 27, 2005
Completion Date: Tue Oct 11 2005
Objectives
 Create subclasses.
 Create abstract classes.
 Override methods.
In this assignment, you will extend the two parts of assignment 1, getting lots of experience with
inheritance. As in assignment 2, you will process input lines consisting of both word sequences, digit
sequences, and left and right parentheses. In the first and second parts of your assignment, you will create
different kinds of tokens as instances of different classes, and use the default implementation of
toString() to print these instances. These classes will be arranged in an inheritance hierarchy given to
you. In the third part, you will override toString() to create a better printout. These two parts, thus,
build on parts 2 and 3 of the previous assignment.
In part 4 of this assignment, you will add the point class defined in lectures to the mix of shape and
rectangle classes you have created in assignment 2, and refactor them so they share code by creating an
inheritance hierarchy defined by you.
In part 5, you will do a more challenging inheritance problem, where you will redo the scanner of this
assignment to make it a subclass of the scanner of the previous assignment, refactoring the former if
necessary.
As before, each of the parts will involve writing a separate main class.
As mentioned in lectures, for all assignments, each class you instantiate must implement an interface,
which should be used to type variables/parameters that are assigned instances of the class.
Part 1: Creating a token hierarchy
The previous assignment reduces all tokens to the single type: String. In this part, associate different token
kinds with different classes declared by you, arranged in the following class hierarchy:
AParameterListStart and AParameterListEnd are classes for the tokens you create
for ‘(‘ and ‘)’.
Here, if class A is indented respect to another class B, then B is a subclass of A. Thus, in the above
example, ANumber is a subclass of AToken which is a subclass of Object. You can initially make
these classes empty, for e.g.:
public class AParameterListStart extends AToken {
}
and later add methods (and interfaces) as you do the subsequent parts of this and future assignments. Once
you understand abstract classes, make appropriate classes in this hierarchy as abstract. You can identify
abstract classes later, so don’t wait for abstract classes to be covered before starting on this part.
Part 2: Enumerating a token hierarchy
Create a new enumerator that enumerates instances of these classes rather than strings. Define an
appropriate interface for the class. Write a main program that uses System.out.println() to print
each token enumerated by the new scanner, which in turn simply calls the toString() method of the
token inherited from class Object. Figure 2 shows the desired output. For this part, you will be modifying
the scanner from the previous assignment. However, create a new copy and give it a different name, as in
part 5, you will be referencing both scanners simultaneously.
Figure 1 Printing instances of token classes
Part 3: Overriding toString()
Figure 2 does not give the string corresponding to a token. Override the default toString() method
(inherited from the class, Object) to return what it does concatenated with, within parentheses, the string
corresponding to the token, as shown in Figure 3. To do this part, you may have to add additional
methods/constructors besides toString() to one or more token classes. You should make as few
changes to the token classes as possible.
Figure 2 Adding token string to default toString()
Part 4: Shape Hierarchy
The two shape classes you created earlier for rectangles and ovals were independent. As a result they did
not share code. Moreover, they do not share code with ACartesianPoint defined in chapter 2 on
objects. Redo these three classes so they share code by defining an appropriate inheritance hierarchy. The
hierarchy should be defined for both classes and interfaces. The refactoring should result in:
 An abstract class that is inherited by all shape classes.
 An abstract class that is inherited by the rectangle and oval classes.
 An interface that is implemented by all shape classes. This interface (let us call it Shape)may be
implemented by a shape class directly or indirectly. Thus a shape class can implement an
interface that extends Shape.
Part 5: Scanner Subclassing
Re-implement the scanner of this assignment so that it becomes a subclass of the scanner for the previous
assignment. It may implement a different interface. In fact, if your previous scanner class enumerated
strings, then this class will implement an additional interface that enumerates tokens. The new interface
would have to give different names to the methods to avoid conflicts. You are free to refactor the previous
scanner to make it more amenable to sub-classing. For example, you can rename nextElement() in the
previous scanner to nextString(). However, you should not change the behavior of the public
methods implemented by the previous scanner, though you can change their names, as illustrated above.
Extra Credit
If you did not do so earlier, you can do the extra credit part of the previous assignment, which should be
easier now that you know inheritance.
Submission Instructions
Submit:
1. A printout of all of the classes and interfaces you end up with after you have finished all parts.
2. Screenshots to show parts the parts 2 and 5 working. You do not have to show screen shots for part 1.
If you don’t get part 5 working, then show screen shots for part 3. You must select appropriate test
cases to demonstrate your solutions, in particular, those used in the screen shots given above. In all
assignments, you will be graded on the test cases you choose.
3. In the write up you submit:
 indicate which abstract classes/concrete classes/interfaces were used
 explain how exactly you used inheritance in this assignment by identifying the methods you
reused in subclasses.
 explain how interfaces helped make the program more elegant.
 explain the advantages of your inheritance solution over your non-inheritance solution in the
scanner implementations.
As before, upload the assignment directory to by midnight of the day the assignment is due and do not
change the code after you submit it in class.