In this assignment, we'll explore Association by building a virtual Train!
As before, all the files necessary for this assignment are contained within this repository. When you submit, please remember to include:
- all files necessary to compile your program
reflection.mdcontaining your reflections and notesrubric.mdwhere you document which elements of the assignment you have attempted and/or completed.
For this assignment, you'll be writing four interrelated classes:
- The
Passengerclass (Passenger.java) will store information about an individual passenger - The
Engineclass (Engine.java) will represent the locomotive engine, storing information about its fuel type, level, etc. - The
Carclass (Car.java) will be used as a container forPassengerobjects - and the
Train(Train.java) class will tie them all together
You'll also notice a 5th file in the repository (FuelType.java), which contains something that looks like an extremely simple class:
public enum FuelType {
STEAM, INTERNAL_COMBUSTION, ELECTRIC, OTHER;
}
In Java, we can use the keyword enum to establish simple type that must take as its value one of a set of predefined constant values. We'll use this in the Engine class instead of a String to keep track of what kind of fuel the Engine uses. You don't need to change this file, but you can use the values it contains like this:
FuelType f = FuelType.ELECTRIC;
Let's pause a moment to think about the different kinds of relationships we'll want to establish:
- The
Trainclass should have a composition relationship with theEngineclass (if you remove theEngine, it ceases to be aTrain, and if you destroy theTrain, you get rid of theEngineas well). - The
Trainclass has an aggregation relationship with theCarclass (theTrainhas a collection ofCarsassociated with it at any given time, but you can add / removeCarswithout destroying either theTrainor theCarsthemselves). - The
Passengerclass has association relationships with theCarclass (Passengers boardCars as their means of using theTrainto move around more efficiently).
We recommend you start by implementing the Engine class. Your Engine class will need:
- a private
FuelTypeattribute to indicate what type of fuel it uses, anddoubles to store the current and maximum fuel levels (along with an approproate accessors for each) - a constructor, which takes in initial values for the attributes named above and sets them appropriately
- a method
public void refuel()which will reset theEngine's current fuel level to the maximum - a method
public void go()which will decrease the current fuel level and print some useful information (e.g. remaining fuel level) provided the fuel level is above 0 (otherwise it should throw aRuntimeExceptioncontaining an informative message)
You can use the main method defined below as a starting point for testing:
public static void main(String[] args) {
Engine myEngine = new Engine(FuelType.ELECTRIC, 100.0);
try {
while (true) {
myEngine.go();
}
} catch (Exception e) {
System.err.println(e.getMessage()); // Out of fuel
}
}
Next, we'll set to work on the Car class. The Car class will need:
- a private
ArrayListwhere it will store thePassengers currently onboard, and anintfor theCar's maximum capacity (sinceArrayLists will expand as we add objects, we'll need to manually limit their size) -
- a constructor, which takes in an initial value for the
Car's maximum capacity and initializes an appropriately-sizedArrayList
- a constructor, which takes in an initial value for the
- accessor-like methods
public int getCapacity()andpublic int seatsRemaining()that return the maximum capacity and remaining seats, respectively - methods
public void addPassenger(Passenger p)andpublic void removePassenger(Passenger p)to add or remove aPassengerfrom theCar(Hint: don't forget to check that there are seats available if someone wants to board, and to confirm that thePassengeris actually onboard before trying to remove them! If you encounter a problem, throw aRuntimeException.) - and a final method
public void printManifest()that prints out a list of allPassengers aboard the car (or "This car is EMPTY." if there is no one on board)
Now that you've got a functional Car class, the Passenger class can be expanded to use the Car's methods to implement some of its own:
public void boardCar(Car c)can callc.addPassenger(this)to board a givenCar(Hint: this method should be ready tocatchtheRuntimeExceptionthat will be thrown byc.addPassenger(...)in the event that the car is full.)public void getOffCar(Car c)can callc.removePassenger(this)to get off a givenCar(Hint: this method should be ready tocatchtheRuntimeExceptionthat will be thrown byc.removePassenger(...)in the event that thePassengerwasn't actually onboard.)
Now we're in the home stretch! To assemble your Train, you'll need (at minimum):
- a private
Engineattribute, which we will mark with the keywordfinalto establish the composition relationship (e.g.private final Engine engine;) - a private
ArrayListto keep track of theCars currently attached - a constructor
public Train(FuelType fuelType, double fuelCapacity, int nCars, int passengerCapacity)which will initialize theEngineandCars and store them - a couple of accessors:
public Engine getEngine()public Car getCar(int i)to return theith carpublic int getMaxCapacity()which will return the maximum total capacity across allCarspublic int seatsRemaining()which will return the number of remaining open seats across allCars
- and finally, its own
public void printManifest()that prints a roster of allPassengers onboard (Hint: yourCars can help!)