Lab 3: Inheritance


class Vehicle {
    public Point2d getPosition() {}
    public float getVelocity() {}
}

Consider a (fanciful) class Vehicle. A quick shell of a definition above shows a couple of useful accessors that perhaps could apply to any vehicle. Every vehicle has a position and a velocity. (Presumably this object would need some mutators, some private data elements, and at least one decent constructor to actually be useful. I leave these out for brevity of example!)

Inheritance is one nice way to enable code reuse in an object-oriented setting like Java. What if I want to represent a motorized vehicle? Certainly it's reasonable to assume that a motor vehicle "is a" vehicle, but motor vehicles also probably have a fuel tank and, at least in the state of California, a license plate.

class MotorVehicle extends Vehicle {
    public float getFuelRemaining() {}
    public String getLicensePlate() {}
}

The extends keyword is the gateway to using inheritance in Java. When a class extends another class, it adds (and/or replaces) functionality in its parent class. Other jargon: MotorVehicle derives or inherits from Vehicle, it is a child class, and Vehicle is its superclass or parent class.

Note well that even though MotorVehicle is the child class, it has more functionality than its parent. Our understanding of vehicles in general tells us that any motor vehicle is a vehicle, but every vehicle is not necessarily a motor vehicle. Inherited objects maintain this "is a" relationship. It should be clear to you that given any MotorVehicle, I can call any of its methods or any of its parents' methods:

MotorVehicle myNiceCar = new MotorVehicle(/* etc. */);
if (myNiceCar.getFuelRemaining() == 0) {
    System.out.println("We're out of gas.");
    sendOnStarMessage("Please send a tow truck to " + myNiceCar.getPosition());
}

Except in special cases, any class can be extended, including child class MotorVehicle:

class Semi extends MotorVehicle {
    public void useCB(int channel) {}
}

Subclassing subclasses often yields a lengthy derivation tree:

Vehicle
  |
  +--MotorVehicle
        |
        +--Semi

Here's a derivation tree for the class JButton, an object which represents a button in the Swing graphical user interface:

java.lang.Object
  |
  +--java.awt.Component
        |
        +--java.awt.Container
              |
              +--javax.swing.JComponent
                    |
                    +--javax.swing.AbstractButton
                          |
                          +--javax.swing.JButton

You'll need to be comfortable with these inheritance trees to find the methods you need in the Java API docs. Take a look at class JButton in the docs and scroll down to where it lists the methods. Right below those, it lists all of the methods included from the direct parent, and then the ones from the grandparent, etc. If you're looking through the javadocs trying to figure out if there's a method to set the text on a JButton, for example, it's important to look at the inherited methods as well. (You'll find setText(String) to be a method of AbstractButton.)

What you need to do:

  1. Read about the javadoc documentation format (also see this page). You do not have to use the javadoc tool itself, but we encourage you to write javadoc-compatible comments before every class and method. In particular, each method should include the @param and @return tags describing the inputs and outputs to the methods, along with the @throws tag if the method throws any exceptions.

  2. Check out Lab3starter.java. This class implements a very simple graphical interface using the Java Swing API. None of the buttons actually do anything (besides click) and when you close the window, the program won't actually fully exit. You'll have to hit Ctrl-C to stop the Java VM.

  3. Add a creative title to this window via a method you find via in the javadocs. The title will appear in the title bar, which sits above every window in most window managers.

  4. Switch to a GridLayout. Use a 2x2 grid.

  5. Now that you're adding three JButtons to a layout with spaces for four components, add a fourth JButton that has an image on it instead of a text label. (Hint: images are represented as Icons in Swing, and the Icon class is an interface -- that means you can't actually instantiate it. Instead, look for a class which implements the Icon interface that does what you want. You'll need a nice small image in your directory to use for this.)

  6. Define a new class Point2dButton that extends JButton. Within this new class, define:

  7. Replace the empty JButton in the first grid cell with one of your new Point2dButtons. After you pack() and show(), demonstrate that your button can return the Point2d by printing the coordinates of it with System.out.println(). Note that this does not mean that the coordinates get printed when you click the button (we'll deal with that next week). Instead, just call the accessor of your Point2dButton instance to get the stored Point2d instance, and print its x and y coordinates.

  8. Rename Lab3starter to Lab3 (both the class and the file) and place these and the Point2dButton.java file in your regular cs11 directory structure.