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.md
containing your reflections and notesrubric.md
where you document which elements of the assignment you have attempted and/or completed.
For this assignment, you'll be writing four interrelated classes:
- The
Passenger
class (Passenger.java
) will store information about an individual passenger - The
Engine
class (Engine.java
) will represent the locomotive engine, storing information about its fuel type, level, etc. - The
Car
class (Car.java
) will be used as a container forPassenger
objects - 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
Train
class should have a composition relationship with theEngine
class (if you remove theEngine
, it ceases to be aTrain
, and if you destroy theTrain
, you get rid of theEngine
as well). - The
Train
class has an aggregation relationship with theCar
class (theTrain
has a collection ofCars
associated with it at any given time, but you can add / removeCars
without destroying either theTrain
or theCars
themselves). - The
Passenger
class has association relationships with theCar
class (Passenger
s boardCar
s as their means of using theTrain
to move around more efficiently).
We recommend you start by implementing the Engine
class. Your Engine
class will need:
- a private
FuelType
attribute to indicate what type of fuel it uses, anddouble
s 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 aRuntimeException
containing 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
ArrayList
where it will store thePassenger
s currently onboard, and anint
for theCar
's maximum capacity (sinceArrayList
s 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 aPassenger
from theCar
(Hint: don't forget to check that there are seats available if someone wants to board, and to confirm that thePassenger
is 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 allPassenger
s 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 tocatch
theRuntimeException
that 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 tocatch
theRuntimeException
that will be thrown byc.removePassenger(...)
in the event that thePassenger
wasn't actually onboard.)
Now we're in the home stretch! To assemble your Train
, you'll need (at minimum):
- a private
Engine
attribute, which we will mark with the keywordfinal
to establish the composition relationship (e.g.private final Engine engine;
) - a private
ArrayList
to keep track of theCar
s currently attached - a constructor
public Train(FuelType fuelType, double fuelCapacity, int nCars, int passengerCapacity)
which will initialize theEngine
andCar
s and store them - a couple of accessors:
public Engine getEngine()
public Car getCar(int i)
to return thei
th carpublic int getMaxCapacity()
which will return the maximum total capacity across allCar
spublic int seatsRemaining()
which will return the number of remaining open seats across allCar
s
- and finally, its own
public void printManifest()
that prints a roster of allPassenger
s onboard (Hint: yourCar
s can help!)