Laboratory 11: The Class Menagerie

April 18, 19, 2006

Bring your Java, Java, Java text to the laboratory.

Objectives

The objectives of this laboratory are
  1. To reinforce the concepts of inheritance and polymorphism
  2. To give practice extending classes and implementing interfaces
In preparation for this lab you should review Chapter 8, especially Section 8.3, of Java, Java, Java.

Overview

In this lab, we begin with the definition of the Animal class given on page 360 of the text. Following the examples in the book, we will implement our own subclass of Animal (other than Cow, Cat, and Pig). We will then modify the Animal class definition by adding the abstract method eat(). We will implement the eat() in our Animal subclasses, including the new subclass that we defined in lab. Finally, we will define the Trainable interface and provide implementations of its doATrick() method in our Animal subclasses.

By the completion of the lab, we will have a program that will generate the following output:

I am a cow and I go moo
I eat hay
I am a cat and I go meow
I eat mice
I do tricks. I can hang from the drapes.

Problem Decomposition

This project will involve the Animal class, the Cat subclass, and the subclass that you will define. The Animal class is currently designed as follows:
Animal
# kind: String
+ Animal()
+ toString(): String
+ abstract speak():String
+ static main(args: String[])

Implementation

Step 1. Set Up.

Download the following files into your lab11 directory:

Step 2. Compile and run the downloaded files.

Modify the main() method in the Animal class so that it no longer refers to the Pig class, which we won't be using in this lab. Then compile and run the Animal class using:

    javac Animal.java
    java Animal

Step 3. Define your own Animal subclass.

Following the example of the Cat and Cow classes, define your own subclass of Animal. Implement its speak() method in a way that is appropriate for that animal.

Step 4. Defining and testing a new inherited behavior.

Modify the Animal class by defining an abstract eat() method. This method has no parameters and returns a String(). Then modify the Cat and Cow subclasses and the subclass that you created so that all three classes implement the eat() method. When you're done with this step, your program should generate something like the following output:

I am a cow and I go moo
I eat hay
I am a cat and I go meow
I eat mice
I am a dog and I go woof
I eat carpets

Step 5. Defining the Trainable interface.

The Trainable interface has the following design:

<<interface>>
Trainable


+ abstract doATrick():String

Provide an implementation of the Trainable interface for both the Cat class and the class you defined. To implement an interface you must modify the class definition and then provide an implementation of all the methods defined in the interfaace. In this case you would modify the Cat definition to:

    public class Cat extends Animal implements Trainable

You would then provide a definition of the doATrick() method in the Cat class. This is similar to the way you defined an implementation of the actionPerformed() method when you implemented the ActionListener interface in the GUI files of previous labs.

To test your code, modify the main() program to include the following lines:

    Trainable pet = new Cat();
    System.out.println(pet.doATrick());

Modify main() so that it also calls doATrick() on the Animal subclass that you created.

Step 6. Questions.

Given the classes and interfaces you have defined, which of the following would be valid. Explain. If you don't know the answers, experiment by typing the code into your program and testing it.

Step 7. Optional Challenge

If you've finished the other parts of this lab and would enjoy an additional challenge, try this problem: Define a new interface named Predator, which contains the preysOn() method. This method takes a single parameter of type Animal and returns a boolean. For a class that implements this interface, the preysOn() interface would define all the animals that that animal preys on.

To test this method define an Animal subclass such as Wolf that preys on Cats and other small animals. One way to implement preysOn() would use the built-in instanceof operator. This is a boolean operator that has the form obj instance class. For example, if you have created a String instance named str, then str instanceof String would be true.

Hand In.

Before handing in your programs, be sure to document your source code. Every method must have a comment block that describes the method, its parameters, and its return value.

Have your work checked by the laboratory instructor or TA. Print out and hand in a copy of the Animal.java, Cat.java files and the source code for the class you created.

You're done. Great work!