We’re looking at SysInventory.java, the object class holding a whole array of ITSystems, the system inventory.
Idea of a helper method. Here doCommands is called from main, and to do its work, calls whichITSystem and processActionsForITSystem, which call other methods. These methods that never get called from outside the class are called helper methods.
Note that system.recordProblem(), a call in processActionsForITSystems, is not a helper, because it involves a call between classes, in this case from SysInventory into ITSystem. On the other hand, promptInt and prompt are more helpers.
We’ve seen how private fields hide data away from other-class code. Similarly private methods are hidden in their classes, away from other-class code. When we mark a method private, it means we’re using it as a “helper” to the other methods in the class, so it isn’t expected to be called on its own. It’s not in the API. The API consists of the public methods and constructors.
SysInventory’s API is as usual the set of public methods and constructors:
SysInventory(String name)
void open(Scanner input) // set up the inventory, with help of input
void doCommands() // process commands: exit, help, print, record-problem, others to be added
That’s it—no getters here. To find out things, the user has to enter commands. Of course we could add a “getName()” method, but we don’t need it.
Example of coding with this system—add a field “hostname” and support lookup by it.—postponed to next time. That discussion will help with #4, where you add a feature to find the system to work on by room number. So concentrate on earlier problems before then, and the narrative of #5.
First we add hostname to ITSystem as a private field, and give it a getter.
Now want to change whichITSystem to work with hostname lookups as well as id lookups.
Suppose system “tom” is 1 and “jerry” is 2
Desired behavior:
Enter system inventory number, 0 to quit, or host <hostname>: 2
whichSystem returns systems[2], an ITSystem object
Enter system inventory number, 0 to quit, or host <hostname>: host tom
whichSystem returns systems[1], the ITSystem with hostname “tom”
We can detect if it’s a number with scanner.hasNextInt(), then if so, read it with nextInt(), handle as before
and if not, with next(), check if it’s “host”, and if so, read another token with next() for the hostname, and try to find it
In cases that don’t provide a system, we loop back
The demo went very badly. I had to start over after messing up the first version and not seeing a way out. That reminded me to tell you about backing up your files periodically so you can go back if you paint yourself into a corner like this. It happens to everyone every once in a while.
On the second try of editing SysInventory, I got as far as the scanner.nextInt(), but it failed. Putting scanner.next() instead of scanner.nextInt() showed proper numeric input. I gave up at this point to avoid wasting more time. On getting back to this code later, it worked fine to restore the nextInt(), so I think I somehow didn’t really compile the nextInt() code the first time. The finished code is now available as ITSystemWithHostName.java, SysInventoryWithHostName.java and SysInventoryWithHostNameMain.java in the p2 files directory linked to the class web page (where ITSystems.java, etc. are available).
DrJava Points
How to goto line after an error during a run: read the backtrace to the first line that lists one of your own classes, note the line number there. Select Edit in DrJava, with the class code showing, find “Go to” and then Go to Line, and fill in the line number. The cursor is put on that line.
How to match up curly braces: Put the cursor just to the right of the opening or closing curly brace, and It highlights the whole block of code inside the matching curly braces. This can fail to work if there are syntax errors within the area, or perhaps even outside the area, so try to fix up everything you can before trying this.
How to indent program: select the whole file with “Select all” under Edit or control-A. Then right click and select “Indent Lines”. If it doesn’t work, that means there is a compile error that you need to fix first.
We have been writing down APIs as a compact representation of the behavior of a class. Java has a similar construct, though it doesn’t have the constructors listed, just public methods. For example
API for Automobile
Automobile(String make, String model, int year, String
vehicleID)
String getMake() car’s make
String getModel() car’s model
int getYear() car’s model year
String getVIN() car’s vehicle ID
Quick example of use:
Automobile car = new Automobile(“Toyota”, “Camry”, 2011, “1GH1234567”);
System.out.println(“car’s year is “+ car.getYear());
Suppose we want to work with Automobiles and Trucks, and have a Truck type like this:
API for Truck
Truck(String make, int truckClass, String vehicleID)
//avoiding “class”
String getMake() truck’s make
int getClass()
truck’s class (1 to 8)
String getVIN() truck’s vehicle ID
Quick example of use:
Truck truck = new Truck(“Toyota”, 3, “1GH1234567”);
System.out.println(“truck’s class is “+ truck.getClass());
Now we see that our cars and trucks both have makes, and VINs. We can capture this commonality and use it in programs.
public interface Vehicle {
String getMake();
String getVIN();
};
This declaration creates a new type called Vehicle, and we can say:
An Automobile IS-A Vehicle
A Truck IS-A Vehicle
These are actually technically accurate statements, using the IS-A relationship. Automobile IS-A Vehicle means that Car objects can do all the actions specified by the Vehicle interface. Since the actions define what a Vehicle is, you see it makes ordinary sense too. A Vehicle is an object that can provide its make and VIN. An Automobile can provide its make and VIN, so it’s a Vehicle. Similarly a Truck is a Vehicle.
To state this in Java:
public class Automobile implements Vehicle {
… just as before: fields, constructors, methods
}
public class Truck implements Vehicle {
//Truck fields, constructor(s), methods
}
Example of use of Vehicle: We can’t do new Vehicle(…), since Vehicle has no constructors (and interfaces never can have constructors). But we can create Automobiles/Trucks and call them Vehicles.
Remember, a Truck IS-A Vehicle, so there is “type compatibility”
Vehicle v1 = new Automobile(“Toyota”, “Camry”, 2011, “1GH1234567”);
Vehicle v2 = new Truck(…);
Now we can use the interface methods on v1 and v2
System.out.println(“ v1 has make “ + v1.getMake());
System.out.println(“ v2 has make “ + v2.getMake());
The power of this shows up more if we put these Vehicle objects in an array:
Although we can’t “new” a Vehicle, we can “new” a Vehicle array (it’s just a sequence of reference slots, no Vehicle objects)
Vehicle[] vehicles = new Vehicle[10];
vehicles[0] = v1;
vehicles[1] = v2;
…
End up with 10 cars and/or trucks. We can count the Fords across cars and trucks, look for a certain VIN, etc.—next time.