CSCI 201 Lab 13 -- Inheritance in Java

Getting started

If folders C:\files\Pets or C:\files\Frames exist on your machine delete them.

How Heritance Works in Java

As discussed in Chapter 7, Java allows you to define a new class as a subclass of a previously defined class. This means that your new class can automatically possess, or inherit, useful features of the original class. All you have to do is state that your new class extends the existing class, which is called the superclass of your new class. If you start your class definition this way, then you only have to provide any additional data and methods which your more specialized class requires.

This concept in fact allows you to build "subclasses of subclasses" in Java, where a class derived from some superclass may itself be used a superclass to derive even more specialized classes. In fact Java is based on the notion of a so-called "tree" of classes, which is usually called the class hierarchy.

Your Task

In this lab, you will have a chance to work with two short projects designed to illustrate the key concepts and features of inheritance. The first is a console application dealing with household pets, which is based on a simple class hierarchy that can be represented as


Object
  Pets
    Cat
      AlleyCat
    Dog
Before you start to panic, be assured that most of the classes in this hierarchy have already been written for you. Your major task will be simply to define the class AlleyCat and test its features.

The second project will be a simple windows application, which will use an existing "generic" window class named java.awt.Frame to create and display a toplevel window for a "toy" application. Again, this will only take a few lines of code on your part.


Instructions for Project 1

  1. Start JCreator and create a new Empty Project named Pets.
  2. Download the following source files and import them into your Pets project folder:

    Pet.java Cat.java Dog.java Pets.java

    "Pet.java" defines a class Pet, which is intended to represent a generic sort of household pet (cat, dog, hamster, whatever). In other words, Pet serves as a superclass from which we can derive various subclasses like Cat or Dog to define more specific types of pets.

    Now most pets, including most cats and dogs, are given some sort of name (whether they know it or not). So it makes sense to provide the Pet class with data and methods that deal with a pet's name. Before proceeding, you should read through the Pet class definition to check out these features. While you are looking, verify that Pet does not explicitly use extends in its header line. This means that Pet is a direct subclass of Object.

  3. If you now open the file "Cat.java", you will see the class header line

    public class Cat extends Pet

    This means that Cat is defined to be a subclass of Pet, which in turn means that every Cat automatically inherits all the public and protected methods of Pet. If you read through the set of class methods for Cat, you will find no methods called either setName() or getName(), but any Cat object does have both methods because it has inherited them from Pet. However, the Cat definition does add in some specialized methods that not all pets should possess, as for example meow().

    As you read through the Cat definition, you will also notice some methods that make references to objects of the class Dog, which is also included in this project. These methods are provided here to allow some "message-passing" to go on between Cat and Dog objects. While they illustrate other important principles of object oriented programming, these message-passing features are not directly related to inheritance. Actually, in this lab they are just a cheap ploy to introduce gratuitous violence into an otherwise boring console application.

    You can verify this for yourself by compiling and running this application now, before proceeding to the next step.

  4. Now you need to add a new Java source file to this project, in which you will define a subclass of Cat named AlleyCat. To do this, just select File/New, choose the Java File option, and then enter the name AlleyCat into the edit box.
  5. Next you should proceed to define an AlleyCat so that it extends Cat, and implements the following additional methods:

    1. public void hiss ()
    2. public void snarl ()

    You should implement these methods so that they simply print the console messages "Hiss!!!" and "Snarl!!!" respectively.

  6. Finally, it seems appropriate to make an AlleyCat more assertive even when it just "meows". This gives you an opportunity to override a method inherited from Cat, namely meow(). To do this, simply locate the meow() method in Cat.java and copy the entire method into AlleyCat.java. Then change its console message from "Meow!" to "MEOW!!.
  7. This completes the definition of your new AlleyCat class. Now you need to test the behavior of an AlleyCat. To do this, open the project application file Pets.java. Locate the lines that create and "introduce" a new Cat object. Copy these lines and modify them so that they create and introduce a new AlleyCat, as well as the original Cat. Also add in lines that let the AlleyCat show that it can hiss and snarl. To restore peace and quiet to the application, you might also want to locate and "comment out" the line that starts the fight between the Cat and the Dog.

    Compile and run the project, and verify that your AlleyCat behaves as required.


Lab Check-off 1

After you have completed and tested your new AlleyCat class, show the source file to your instructor. Demonstrate its behavior by running the program.


Instructions for Project 2

  1. Start JCreator and create a new Empty Project named Frames.
  2. In this project, create a new java source file to define a class TestFrame, which extends the standard Java library class java.awt.Frame. Incidentally, to save yourself some writing, it would be best to precede your new class definition with the two import statements
    
    import java.awt.*;
    import java.awt.event.*;
    
    Among other things, you can then simply write Frame instead of java.awt.Frame in this file.

    Next go ahead and write the header line for the TestFrame class definition, and follow it with an empty pair of curly braces. In the following steps you will start to add data and methods to this class.

  3. Your new TestFrame will inherit a lot of functionality from the basic Frame class. In fact, the major point of this exercise is to show just how little it takes to start building a specialized windows application if you just subclass "off-the-shelf" classes like Frame. But before you start to make a true subclass of Frame, you should see what the Frame class itself can do. To check this, just include the following main() method in "TestFrame.java":
    
      public static void main (String [] args)
      {
        Frame f = new Frame ("Test Frame");  // Makes toplevel window with title
        f.setSize (400, 300);                // Initial width=400, height=300 
        f.setVisible (true);                 // Makes window appear on screen
      }
    
    In general, a class may include a main() method like this to create and test objects of its own class. Later you will change this code slightly to create a TestFrame object, but as it stands this code creates an ordinary Frame instead.

  4. Now you should attempt to compile and run this application as it stands. Once you fix any compiler errors and actually start it running, you should see the following blank window appear in the upper left corner of the screen:

    You should check out the behavior of this window. You will find it has all the usual features, except for one: you cannot close it by clicking the little X in the rightmost part of the window manager bar. In fact, this is the only major failing of the Frame class. The only way you can close this Frame just now is to select the console window and enter a ctrl-C from the keyboard. Incidentally, this will kill both the Frame and the console window.

  5. Now you will proceed to make TestFrame a true subclass of Frame, by customizing it to provide at least one civilized way to dismiss the window. First, you need to add the following new member variable:
    
      private Button exit;
    
    Then write in the following constructor:
    
      public TestFrame (String title)
      {
        super (title);     // Invokes superclass (Frame) constructor used above
    
        exit = new Button ("Exit");    // Creates new Button with "Exit" label
    
        setLayout (new FlowLayout ()); // Creates object to control window layout
        add (exit);                    // Adds button component to window
      }
    
    Finally, go back to main() and change the first line to
    
        TestFrame f = new TestFrame ("Test Frame");
    
    With this step main() will now be testing a true TestFrame object.

  6. Now attempt to compile and run the project again. If all goes well, the window should now appear as shown below:

    But unfortunately, you will soon discover that clicking the Exit button does not yet dismiss the window. Of course it is not enough for it to have the label "Exit". As the final stage in this exercise, you will now introduce an event handler that can react to the user click on this button and stop the application.

    This part takes two separate steps. First, you need to provide an object which is "qualified" to receive the "button-click" category of system event messages. Now it turns out that you can make the TestFrame itself qualified to deal with these messages. To do so, it only has to implement the ActionListener interface. In other words, the class header must be modified to include the clause

    
        implements ActionListener
    
    which implies that TestFrame must provide a method whose header has the form
    
        public void actionPerformed (ActionEvent e)
    
    Now when everything is set up correctly, this method will be invoked by the runtime system whenever the Exit button is clicked. So you want to implement this method in such a way that it will close the window and terminate the application. You can accomplish this by writing the following statements in the body of the actionPerformed() method:
    
        setVisible (false);      // Makes window disappear from screen
        dispose ();              // Frees up any window resources
        System.exit (0);         // Stops Java Virtual Machine (JVM)
    
    Now make these additions to your TestFrame definition, compile the project, and run it again. But do not be disappointed if the Exit button still doesn't work, because there is still one small step left...

  7. The only remaining problem is that the TestFrame is not yet being notified by the runtime system when the user clicks the Exit button. By now it is fully qualified to respond to such events, but it just is not getting the word. Now in the Java "event model", any object which may be the source of an event (like the Exit button) must set up a list of qualified listener objects that the system should notify when the event happens. The system will notify all objects in that list, but no others.

    This all means that the Exit button must add the TestFrame to a list of ActionListener objects that will be notified when the user clicks the button. To do this, just return to the TestFrame constructor. Immediately after the line that creates the new Exit button object, add the single line

    
        exit.addActionListener (this);   // Notify TestFrame if button clicked
    
  8. Then once again, compile and run the project. With luck, you will see that your fine Exit button is finally doing its job. If so, it is time to quit while you are ahead, at least for this lab...

    ...But for those with inquiring minds, who may also want to know how to close the window via the little X in the manager bar, try creating a new JCreator LE project using the Basic Java Application option. With this option you get an initial "freebie" source file that makes a Frame subclass with a "window closing" event handler. The technique used here is to create an object of an anonymous inner class to handle so-called "window" events. While your book does not cover this approach, please feel free to ask your lecture or lab instructors if you want to know the details.


Lab Check-off 2

After you have completed and tested your program, show it to your instructor.