In this assignment, we'll explore Encapsulation 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 will have a relationship with theEngine
class, because theEngine
is responsible for powering theTrain
. - The
Train
class also has a relationship with theCar
class: theTrain
has a collection ofCars
associated with it at any given time, and you can add / removeCars
as necessary (without destroying either theTrain
or theCars
themselves). - The
Passenger
class has relationships with both theCar
andTrain
classes (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
FuelType
attribute to indicate what type of fuel it uses, anddouble
s to store the current and maximum fuel levels (along with appropriate accessors for each). - a constructor, which takes in initial values for the attributes named above and sets them appropriately
- a
refuel()
method which will reset theEngine
's current fuel level to the maximum, and which doesn't need toreturn
anything - a
go()
which will decrease the current fuel level, print some useful information (e.g. remaining fuel level), and returnTrue
if the fuel level is above 0 andFalse
otherwise.
Remember, OOP is all about deciding which classes are responsible for which parts of the end solution. As you program, consider which of these attributes/methods should be public
, and which should be private
. These questions may be helpful to ask yourself:
- Does another class need to be able to read this value? (If so, it could either be marked
public
or have anaccessor
) - Does another class need to be able to modify this value? (If so, it could either be marked
public
or have amanipulator
)
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);
while (myEngine.go()) {
System.out.println("Choo choo!");
}
System.out.println("Out of fuel.");
}
Next, we'll set to work on the Car
class. The Car
class will need:
- an
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
- accessor-like methods
public int getCapacity()
andpublic int seatsRemaining()
that return the maximum capacity and remaining seats, respectively addPassenger(Passenger p)
andremovePassenger(Passenger p)
methods to add or remove aPassenger
from theCar
and returnTrue
if the operation was successful, andFalse
otherwise. (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, you shouldreturn False
.)- and a final method
printManifest()
that prints out a list of allPassenger
s aboard the car (or "This car is EMPTY." if there is no one on board).
As before, consider which of these should be public
and which should be private
(potentially with accessor
s and/or manipulator
s).
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:
boardCar(Car c)
can callc.addPassenger(this)
to board a givenCar
(Hint: this method should check the value that getsreturn
ed byc.addPassenger(...)
in case the selected car is full.)getOffCar(Car c)
can callc.removePassenger(this)
to get off a givenCar
(Hint: this method should check the value that getsreturn
ed byc.removePassenger(...)
in case thePassenger
wasn't actually onboard.)
Now we're in the home stretch! To assemble your Train
, you'll need (at minimum):
- an
Engine
- an
ArrayList
to keep track of theCar
s currently attached - a constructor
Train(FuelType fuelType, double fuelCapacity, int nCars, int passengerCapacity)
which will initialize theEngine
andCar
s and store them - a few 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
printManifest()
that prints a roster of allPassenger
s onboard (Hint: ask yourCar
s to help!)