public 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. These are left out here for brevity of example.)
Inheritance is one nice way to reuse code 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.
public 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, parent class, or base class.
Note 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, we can call any of its methods or any of its parents' methods:
MotorVehicle myNiceCar = new MotorVehicle(...);
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:
public 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 label 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.)
Here is what you need to do for Lab 3. Make sure to complete every item requested below - not only is it necessary for this lab, but it will help you know how to do the next two assignments.
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 in the terminal window to stop the Java VM. (Also, note that the class name doesn't follow the correct Java naming conventions; you will need to fix that in your submission too.)
The main UI work happens in the initAndShowGUI() method. You can see that it is invoked from main() in a somewhat strange way; we haven't talked about these details yet. So, don't worry about main() for now; we will talk about these details in the future.
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.
Switch to a java.awt.GridLayout. (You can read about this class in the API documentation.) Use a 2x2 grid.
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.)
Define a new class Point2dButton that extends JButton. Within this new class, define:
A question you should ask yourself is, "Does my Point2dButton subclass really need to provide its own field to store the label?" It's obvious that your class needs to store the point object, since the parent class simply isn't designed to store a point. But, the parent class does store the label itself, so your subclass doesn't really need to do that. If your subclass also provided a field to store the label then it would be unnecessarily replicating functionality already provided by the parent class.
Replace the empty JButton in the first grid cell with one of your new Point2dButtons. After you pack() and setVisible(true), demonstrate that your button retains the internal Point2d by retrieving the object you passed in, and printing its coordinates with System.out.println(). (You might want to override the toString() implementation on your Point2d class to make this easy.)
Rename lab3starter to Lab3 (both the file and the class it defines) and place these and the Point2dButton.java file in the appropriate directory. (You might have noticed that the lab3starter class/file doesn't follow the Java naming conventions for classes, but your renamed class and file definitely should.)