Copyright RIT 2007
$Id: writeup.xml,v 1.15 2008/12/10 20:57:18 vcss232 Exp $
This lab provides experience developing classes using inheritance. You will use abstract classes, concrete classes, and interfaces to write a simple program that uses polymorphism.
You are to work on this lab completely on your own.
Read Chapters in Liang on inheritance, interfaces and abstract classes.
Complete the Liang book self-tests for chapters 9, 10 and 11 (on inheritance, abstract classes and interfaces) here (http://www.cs.armstrong.edu/liang/intro7e/testing.html ) .
Each lab has a sequence of activities. Each activity has specific deliverables that will be graded separately.
In this activity you will create a program that creates a class hierarchy of Things and Creatures.
Click here (./docs/index.html) . to see the Javadoc pages that describe these classes. Read this documentation so that you understand what each class does and the behaviors that it provides.
First write a test program called TestCreature to test that the class hierarchy works correctly. The TestCreature class contains the main method. The main() must create an array of Thing instances of size THING_COUNT; see javadocs for the value. Create the array and fill it with Thing instances (any non-empty name will do). Next main() must scan through the array and print the String representation of each Thing. Note that you do not need to call the toString() method on each object; just print each object reference from the array directly.
The class Thing is a concrete superclass in the class hierarchy. A client program, such as your test program, can create instances of the class and print them.
The class Creature is an abstract superclass in the class hierarchy. An abstract class represents generalization: a general concept embodied by one or more specific cases. It is illegal to create an instance of an abstract class.
An concrete subclass of a generalization represents a specialization: a specific case of some general concept. The idea of inheritance depends on chains of generalizations and specializations.
Read the documentation for the Thing and Creature classes. Notice that some of the methods have a declaration, and they have no method body. Methods declared but not implemented are abstract methods, which all concrete subclasses must implement.
Read the javadoc comments for the toString() method
for Thing.
The method must create a String that contains
the name of the Thing, followed optionally by the class name.
Since every Thing
instance has a name, that should be a private data member of
Thing.
The class name of a Thing
instance, however, is not a property of the class;
it is a unique property of all of
Thing's
subclasses (and their subclasses).
When you store a reference to a Tiger (for example) in a variable of type Thing, the specific class may be difficult to see. How should you deal with getting the class name of an object reference?
One naive and tempting route to take is to use a series of
instanceof checks on the subclass instance that
invokes
Thing.toString().
|
This chain of instanceof checks is a very poor design practice, because it requires constant maintenance of the Thing class whenever a new subclass is introduced. The paragraphs below describe a BETTER way.
Since all classes inherit from Object,
each class automatically has access to
Object.getClass(),
which returns a reference to the instance's class instance.
With a reference to the Class, get the class name
using
Class.getSimpleName().
These two calls together will
always produce the class name of the instance that is running
the method:
|
After you have written Thing, write Creature, which is an abstract subclass of Thing. Be sure to use the constructor provided by the Thing class when writing your Creature class by calling the super constructor appropriately. Printing a Creature or any of its subclasses, should use Thing.toString(); there is no need to implement toString as a method in Creature.
Note: a Creature. needs to remember only the last thing it eats.
After you have written these classes, compile them and your test program to make sure that they compile without error. Then run these using your test program.
Now write the Tiger class to inherit from the hierarchy. Remember: If a subclass can use a method implementation of a superclass as-is, there is no need to re-write the method. If the method is not private, a client can access it.
Please use a stubbing approach to write the abstract methods of the Tiger. A stub method does nothing except implement a method signature and ensure that the class compiles.
Finally, revise the TestCreature program to create and print a few Tiger instances. Add code to the main() to create several instances of Tiger in the Thing array; this is in addition to the earlier Thing instances. As a result some Thing instances will be Things and others will be Tigers. Make sure that all classes compile without error, and re-run your test program to validate it.
Remember to check in and out your source files whenever you make any major changes and again before submitting them. Part of the grade that you receive on this lab will be based on your use of version control.
After you are satisfied that your classes are correct and you have applied version control (e.g. RCS) to complete the version tags, submit your files using the following command:
|
This activity expands the Thing and Creature framework by adding more creatures and giving them different behaviors.
The next job is to write three more classes, Ant and Fly and Bat that inherit from Creature. You must not modify the Thing.toString() method. Start by reading the javadocs for each class.
Please use a stubbing approach to write a stub for the abstract methods. A stub method does nothing except implement a method signature and ensure that the class compiles.
A Java interface can achieve results similar to multiple inheritance because a single class may implement more than one interface.
Implement an interface called Flyer that specifies the fly() method.
Modify your test program to test the Creatures. The main() must create a separate array for Creature instances. Add a new section of code to create several new Creature instances. Consequently, the main() will have a 'Things:' section followed by a 'Creatures:' section of output. The section for the creatures must simply print the instances (the next activity will revise that).
Below is an example of output for this activity. The 'Creatures:' section evolves in the next activity.
|
After you are satisfied that your classes are correct and you have applied version control (e.g. RCS) to complete the version tags, submit your files using the following command:
|
Please resubmit all files, including those not changed.
This activity completes the program by finishing the stubbed methods the subclasses of Things and Creatures. This means implementing the Creature.eat(), Creature.move(), and Creature.whatDidYouEat() for all the concrete subclasses.
The javadocs describe restrictions on the eating diets of each creature. Read carefully to learn which creatures eat only things, which eat only creatures, and which eat anything.
This activity also requires evolving the TestCreature program to call these new methods and validate their operation. The 'Creatures:' section of TestCreature must now test the methods just implemented in the concrete classes. TestCreature now must have a separate Creature[] array containing references on which to iterate and call the move() method on the different kinds of Creature instances. Note that creatures that move by flying should be using their fly method.
Each class's methods must implement behavior by printing a message to standard output. This message is a simple illustration of different behavior provided by the same message (that is, the same method call on different objects produces different results). This is polymorphism.
Reminder: To invoke a method of a superclass with the
same name from the subclass, prefix the method name
in the call with super., as in
super.toString().
After you are satisfied that your classes are correct and you have applied version control (e.g. RCS) to complete the version tags, submit your files using the following command:
|
Please resubmit all files, including those not changed.
Grade Breakdown: