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.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 will have a relationship with theEngineclass, because theEngineis responsible for powering theTrain. - The
Trainclass also has a relationship with theCarclass: theTrainhas a collection ofCarsassociated with it at any given time, and you can add / removeCarsas necessary (without destroying either theTrainor theCarsthemselves). - The
Passengerclass has relationships with both theCarandTrainclasses (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
FuelTypeattribute to indicate what type of fuel it uses, anddoubles 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 toreturnanything - a
go()which will decrease the current fuel level, print some useful information (e.g. remaining fuel level), and returnTrueif the fuel level is above 0 andFalseotherwise.
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
publicor have anaccessor) - Does another class need to be able to modify this value? (If so, it could either be marked
publicor 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
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 - 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 aPassengerfrom theCarand returnTrueif the operation was successful, andFalseotherwise. (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, you shouldreturn False.)- and a final method
printManifest()that prints out a list of allPassengers 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 accessors and/or manipulators).
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 getsreturned 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 getsreturned byc.removePassenger(...)in case thePassengerwasn't actually onboard.)
Now we're in the home stretch! To assemble your Train, you'll need (at minimum):
- an
Engine - an
ArrayListto keep track of theCars currently attached - a constructor
Train(FuelType fuelType, double fuelCapacity, int nCars, int passengerCapacity)which will initialize theEngineandCars and store them - a few 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
printManifest()that prints a roster of allPassengers onboard (Hint: ask yourCars to help!)
