代写一个大型应用程序,实现一个售票系统。
Backround information
For this assignment you need to write an object-oriented console application
in the Java programming language which adheres to basic object-oriented
programming principles shown below:
- a) Setting the visibility of all instance variables to private.
- b) Only using static attributes and methods when appropriate.
- c) Encapsulating both the data for a class and the methods that work with and/or manipulate that data within the same class.
- d) Using superclass methods to retrieve and/or manipulate superclass properties from within subclass methods where necessary.
- e) Taking advantage of polymorphism wherever possible when invoking methods upon objects that have been created.
The scenario we are modelling is that of ticketing system for a ferry company
in which customers who wish to travel on the ferry can make bookings for a
“standard” passenger vehicle or an oversized vehicle (delivery truck,
passenger coach, etc) to be transported on the ferry.
A standard passenger vehicle booking on the ferry incurs a booking fee of $100
plus an additional $20 booking surcharge for each person travelling in the
vehicle (including the driver).
A standard size passenger vehicle is defined as being less than or equal to
one meter in height.
A ferry booking for an oversized vehicle will attract a surcharge due to their
larger size, so the weight and category for all oversized vehicles needs to be
recorded upon boarding.
Getting Started
In this assignment you will be required to implement an object oriented
program that models some of the basic functionality that may be required to
handle both “regular” Vehicles and ‘oversized’ Vehicles in the Vehicle Booking
System described above.
This task is divided up into several stages, each of which corresponds to the
concepts discussed during the course as shown below:
- Stage 1 - Vehicle class (Writing classes)
- Stage 2 - BookingSystem (Arrays of objects)
- Stage 3 - OversizedVehicle class (Inheritance / subclasses)
- Stage 4 - BookingSystem updates (Polymorphism)
- Stage 5 - Exception Handling (Exception Handling)
- Stage 6 - Persistence to file (File Handling)
- Code Quality (General Concepts)
There is no Startup code for this assignment you are expected to write the
entire program yourself.
A single class called DateTime has been provided to help make working with
dates easier than using the inbuilt Java classes.
Your task begins with the implementation of the Vehicle class.
It of course goes without saying that working your way through the learning
materials for the corresponding weeks highlighted above is strongly
recommended before tackling each of the stages in this assignment.
You are strongly encourage to review the course materials for the
corresponding weeks before starting on the relevant stage, to ensure that you
have sufficient grasp of the underlying concepts to proceed.
Stage 1 - Vehicle class Design / Implementation
Both “normal” Vehicle and ‘oversized’ Vehicles share common details (such as
the registration number, make, year, a description, booking id, and the number
of passengers (including the driver) which are encapsulated in this
superclass.
Some tips below should help you to design and write the Vehicle class:
A) Create the Vehicle Class
The following attributes should be defined in your Vehicle class.
Instance variable | Type |
---|---|
regNo | String |
make | String |
year | int |
description | String |
bookingID | String |
bookingDate | DateTime |
numPassengers | Integer |
Constants | Type |
— | — |
BOOKING_FEE | int |
PASSENGER_SURCHARGE | int |
B) Constructor
You should define a constructor in your Vehicle class.
You should not have a no argument constructor.
The constructor should be responsible for initialising: regNo, make, year and
description to the values provided by the creator of the object.
The constructor should initialise the booking id to “N/A”
C) Accessors (getters)
A simple accessor (getter) should be implemented for regNo.
No other simple accessors should be implemented.
D) Mutators (setters)
No simple setters should be implemented for any of the instance variables..
E) Record Passenger Numbers (Private)
A private method for recording the number of passengers travelling in the
vehicle should be implemented.
This method should return false if an attempt is made to set the passenger
numbers to any value less than 1 or greater than six.
Otherwise, the number of passengers for the vehicle should be set to the
number provided when this method is called.
Floating point numbers are not permitted, the number of passengers must be
represented as an integer value.
This method should be called by the ‘book’ method described below.
If successful the method should return true.
F) Book
A ‘book’ method should be implemented, which calculates and returns a booking
fee based on a fixed value booking fee + a surcharge of $20 for each person
(including the driver) that is travelling with the vehicle. This method uses
negative values to indicate any errors that prevented the booking from being
completed. See the details below.
This method should accept two parameters. One for the number of passengers and
another that accepts a DateTime object set to the date of the booking. The
class for creating the DateTime object has been provided for you on
Blackboard.
Examine this class because it has a number of methods you may find useful to
use when working with dates in your application.
Creating a DateTime object can be done in the following manner.
DateTime date = new DateTime(day, month, year));
—|—
If the number of passengers is not valid then it should return - 1.0 to the
caller of the method and must not complete the booking process.
If the date is in the past then, then it should return - 2.0 to the caller of
the method and must not complete the booking process.
If the number of passengers and the date ARE valid then it should: Set the
booking id to a concatenation of the:
regNo + a date in the format DDMMYYYY
Retrieving the 8 digit format of the date can be done in the following manner.
date.getEightDigitDate();
—|—
For example a car with the registration “AAA123” booked on the 24 August, 2017
should have a booking id of:
SIM47924082017
Set the bookingDate to the date passed into this method.
Calculate and set the bookingFee to the appropriate value.
Return the booking fee to the caller of the method.
Note that “returning” a value does not mean printing a value to the screen.
The value should be returned to the code that calls the function and the
calling code is responsible for deciding what to do with the data provided.
G) Get Vehicle Details
A method should be implemented which returns a description of the vehicle.
This method should build a string and return it to the calling method.
The returned string should be formatted in a human readable form.
The description must include labels and values for all the instance variables
depending on whether a booking has been made.
If the booking id is equal to “N/A” then the number of passengers, bookingDate
and the fee should not be included in the description.
If the booking id is not equal to “N/A” then it should also return all the
details including, bookingId, bookingDate and the number of passengers and the
booking fee.
The method should return a formatted string such that the data is presented in
a human readable format of two columns as shown in the examples below.
Note that “returning” a value does not mean printing a value to the screen.
The value should be returned to the code that calls the function and the
calling code is responsible for the actual printing.
The formatting of the string can be achieved by using the format method on the
String class which operates in the same way as the printf statement you
learned about earlier in the course.
String firstLine = String.format(“%-20s %s\n”, “Reg Num:”, regNo);
—|—
Example 1:
Reg Num: SIM479
Make: Honda
Year: 2007
Description: White Sedan
Booking Ref: N/A
Example 2:
Reg Num: SIM479
Make: Honda
Year: 2007
Description: White Sedan
Booking Ref: SIM47928082017
Booking Date: 28/08/2017
Num Passengers: 4
Fee: $180.00
Stage 2 - BookingSystem class (basic functionality)
Now that the attribute and functionality required for a regular sized vehicle
has been modelled and encapsulated in the Vehicle class described above in
Stage 1. Here, you will begin with the implementation of the BookingSystem
application class, which will use an array, ArrayList or a HashMap of Vehicle
references called vehicles to store and manage vehicles that are added to the
system by the user.
You are not permitted to use streams from Java 1.8. You must use either an
array, ArrayList or a HashMap to store the collection of your vehicles.
- 1.) You should create a class called ‘BookingSystem’.
- A) create a class called ‘BookingSystem’
- B) this class should present a menu to the user for interacting with the program.
- 2.) You should implement a menu feature in the BookingSystem class, for which options are presented to:
- A) Seed data,
- B) Add new Vehicles to the system,
- C) Display Vehicle details and
- D) Book passage on the ferry.
A screen shot showing the presentation of this menu is shown below.
You must implement the menu as shown.
Do not change the options or the inputs for selecting the menu options.
(Note: the letters on the right represent what the user must type to use that
feature. In other words, to add a new vehicle object the user must input ‘A’.
The solution should be case insensitive, that is the user should be able to
enter either ‘a’ or ‘A’)
*** Vehicle Booking System Menu ***
Seed Data A
Add Vehicle B
Display Vehicles C
Book Passage D
Exit Program X
Enter selection:
Your task is to work on the implementation of this initial BookingSystem class
by implementing the functionality for the features shown in the menu.
A description of the functionality that needs to be implemented for each of
these features is provided below.
A) Menu System & Seed Data method
You should implement a method called ‘seedData’ that pre-populates the
vehicles collection with 4 sample vehicles. When this menu item is selected 4
hard coded vehicles will be instantiated and added to the collection.
- Two regular sized vehicles that HAVE been booked
- Two regular sized vehicles that HAVE NOT been booked
If this option is not selected at runtime, then the collection of vehicles
should be empty.
B) Add Vehicle
Create a class called ‘BookingSystem’ and implement the menu shown above.
This first feature ‘Add Vehicle’ should prompt the user to enter all relevant
details for a “regular” Vehicle.
This will be updated later to include Oversized vehicles, but initially you
are only required to handle adding regular sized vehicles.
Once the user has entered the required details, the program should then create
a new Vehicle object accordingly, passing along the details the user has
supplied.
Example:
Enter vehicle registration: SIM479
Enter vehicle make: Honda
Enter vehicle year: 2007
Enter vehicle description: White Sedan
New Vehicle added successfully for registration SIM479.
After the object has been created it should be added to the next (empty) spot
in the array or collection instance that you are using to store the vehicle
objects.
(Note: vehicle registration numbers must be unique in the BookingSystem, so
you will need to validate the registration number entered by the user to make
sure that there is not already another vehicle with the same registration
number in the system.
This should be done by searching the current collection and checking for a
duplicate registration number you should not modify the prescribed constructor
for the Vehicle class nor should you implement automatic generation of unique
registration numbers. )
If the registration number already exists within the array/collection of
vehicle objects then a suitable error message should be displayed and the
program should go back to the menu immediately without creating or storing a
new Vehicle object in the array / collection.
This means that you should perform this check prior to creating the Vehicle
object.
Example 1:
Enter vehicle registration: SIM479
Enter vehicle make: Honda
Enter vehicle year: 2007
Enter vehicle description: White Sedan
New Vehicle added successfully for registration SIM479.
Example 2:
Enter vehicle registration: SIM479
Error - Registration SIM479 already exists in the system!
If you are unsure of how to check for a duplicate registration number then you
can skip the validation for now and come back to it later.
You are not permitted to implement auto generated user inputs such as
registration numbers, but must validate those entered by the user.
C) Display Vehicle Information
This feature should display the details for all objects currently stored in
the array / collection of Vehicle references described above to the screen, by
using a loop to step through the array / collection and calling the
getDetails() method for each object in the array/collection and printing the
returned string to the console.
D) Book passage
This feature should begin by prompting the user to enter the registration
number of the vehicle for which they wish to book passage. Once the user has
entered the registration number the feature should then attempt to locate the
corresponding vehicle object within the array / collection of Vehicle
references described above.
If a matching vehicle with the specified registration number was not found
then a suitable error message should be displayed to the screen.
Example:
Enter registration number: AAA123
Error - registration number not found
Otherwise the feature should then proceed to prompt the user to enter the
requested date of the booking and the number of passengers travelling.
If the booking was not accepted a suitable error message indicating the reason
the booking failed should be displayed on the console.
If the booking was accepted, then the booking cost should be returned by the
method call and printed to the console.
Stage 3 - Oversized Vehicle design / implementation
For an oversized vehicle the ferry company needs to record the vehicle weight
and category (which is used in determining the weight surcharge for booking
fee calculations), on top of the information that is already being stored for
a standard vehicle booking.
You should address this new functional requirement by implementing an
OversizedVehicle class, which extends the basic Vehicle class, as follows:
A) Create the Oversized Vehicle class by extending the Vehicle class
Extend the Vehicle class to define a new subclass OversizedVehicle, which
includes new instance variables for the weight (an int) and category (a
String) for the OversizedVehicle.
Define constant values representing the three weight surcharge rates, as
described in the preamble.
NOTE: You should not need to redefine any of the instance variables that were
defined previously in the Vehicle superclass in this OversizedVehicle
subclass. Whilst a regular sized vehicle has a height it is not important to
record this value for regular sized vehicles, so this attribute is placed in
the oversized vehicle class.
Instance variable | Type |
---|---|
weight | double |
category | String |
Constants | Type |
— | — |
CLEARANCE_HEIGHT | double |
LIGHT_VEHICLE_CHARGE | double |
MEDIUM_VEHICLE_CHARGE | double |
HEAVY_VEHICLE_CHARGE | double |
You should also define any other constants you feel are necessary to prevent | |
repetition of hard coded values used in this class. |
B) Implement a constructor
Implement a constructor for this OversizedVehicle subclass, which accepts the
registration, make, year and description, and clearance height for the
OversizedVehicle as parameters and stores the approprate values in the
corresponding instance variables in the super class.
The constructor should take an additional parameter for storing the clearance
height needed by the vehicle which should initialise the constant in this
class.
You should not add the clearance height to the super class as an attribute
because it is not a requirement of a regular sized vehicle class to store or
make use of a height value.
The category instance variable should also be set to “N/A” initially.
NOTE: You should use the super() facility to pass on the relevant arguments to
the superclass constructor.
C) Implement a unique method
Implement a private method called ‘recordWeight’ which accepts the recorded
weight of the vehicle.
The weight instance variable should be set to the figure specified in the
parameter.
If the vehicle weight has been recorded then the vehicle category should also
be set to either “N/A”, “LIGHT”, “MEDIUM” or “HEAVY”, based on the vehicle
weight, as per the information set out in the preamble.
D) Additional method
Add a new ‘book’ method that takes three parameters: numPassengers (int), date
(DateTime), weight (double) so that it calculates and returns the booking fee
for an OversizedVehicle, which is the sum of the basic fee that applies to
every Vehicle and the weight surcharge for an OversizedVehicle.
This method should first check the clearance height of the vehicle and return
-3.0 if the clearance height of the vehicle exceeds 3 meters.
If the clearance height is less than or equal to 3 then it should attempt to
complete the booking by calling the super class version of the book method to
complete the other basic checks. If the basic checks fail then the result
should be returned to the caller of the method.
Finally, if the booking has been successful at this point it should calculate
the surcharge based on the category of the vehicle and add this surcharge to
the base booking fee.
Assign and return the result to the caller of the method.
Note that the applicable weight surcharge rate is determined by the vehicle
category, as per the information presented in the preamble.
NOTES: You must use the super “reference” to invoke the book() method from the
superclass, in order to calculate the base booking fee, so that it can be used
as the basis for calculating the total booking fee for the current
OversizedVehicle.
Note that “returning” a value does not mean printing a value to the screen.
The value should be returned to the code that calls the function and the
calling code is responsible for the actual printing.
E) Override getDetails method
Override the getDetails()method, so that it prints a full summary of the
details for the current OversizedVehicle to the console.
If no weight is recorded then it should only add the clearance height to the
basic details.
If a weight has been recorded then it should also include the weight and the
category assigned to the
OversizedVehicle).
NOTE: The overriding version of the getDetails() method in this
OversizedVehicle subclass will need to use the super “reference” invoke the
corresponding method from the Vehicle superclass to get the basic vehicle
details first.
Stage 4 - BookingSystem class (updated)
The next stage of this task is to update the BookingSystem application class
implementation described in stage 2 so that it incorporates the ability to
work with OversizedVehicles:
A description of the functions that need to be implemented for each of these
features is provided below.
A) Seed Data
Update your seed method so that it now pre-populates the collection of
vehicles with 4 regular sized vehicles and 6 oversized vehicles. The seeded
data must contain the following variety of vehicles.
- Two regular sized vehicles that HAVE been booked
- Two regular sized vehicles that HAVE NOT been booked
- Three oversized vehicles that HAVE BEEN booked. One from each of the categories (light, medium, heavy).
- Three oversized vehicles that HAVE NOT BEEN booked.
B) Add Vehicle
Update your add vehicle function to now prompt the user to enter the height of
the vehicle.
Once the user has entered all of the required information, if the height
exceeds less than or equal to 1.0, a standard sized vehicle should be created.
Otherwise, a new OversizedVehicle object should be created.
Enter vehicle registration: PUM234
Enter vehicle make: Lexus
Enter vehicle year: 2007
Enter vehicle description: Red Sedan
Enter vehicle height: 1.1
New oversized vehicle added successfully for registration PUM234
The object should be stored in the next available (empty) position in the same
vehicle array/collection described previously in Stage 2.
Note: If you are using a standard array to store the vehicle objects in your
BookingSystem then you should also increment the bookingCount variable to
indicate that there is now one more booking object in the array (if you are
using a standard array).
C) Book Passage (Updated)
This feature should begin by prompting the user to enter the registration of
the vehicle for which they want to make a booking.
Once the user has entered the registration, the feature should then attempt to
locate the corresponding vehicle object within the same vehicles array
described previously in Stage 2.
If a matching booking object with the specified registration was not found
then a suitable error message should be displayed to the screen, otherwise the
feature should then proceed to check the type of the object that was found.
If the type of the specified object is a regular sized vehicle it should
proceed with the booking as normal.
If the type of the specified object is an OversizedVehicle then the feature
should prompt the user to enter the weight of the vehicle in question, and
invoke the constructor of the OversizedVehicle class (note: you will need to
use a typecast here) for the OversizedVehicle object, passing the weight
entered by the user as a parameter.
Note that it is not necessary to re-prompt the user to enter another
registration to search for if the registration was not found.
Enter registration number: RIC888
Enter day of month: 09
Enter month: 09
Enter year: 2017
Enter passengers: 4
Enter weight: 3.5
Booking for RIC888 on 11/11/2017 was successful.
The total cost of the booking is: $145.00
Stage 5 - Adding exception handling to existing functionality
It has been identified that there are potential issues with the booking
process. Currently, these have been handled by returning a code to the user to
indicate the source of the problem.
It has been decided that a better solution is to generate an exception with a
custom error message that will inform the user of the problem that has
occurred.
You should comply with these requests by making the following changes to your
program.
NOTE: When you implement exceptions into your program you will need to modify
your Vehicle, OversizedVehicle and BookingSystem classes to work with the
exeptions.
Exceptions will be generated and thrown in the Vehicle and OversizedVehicle
classes.
Exceptions will be caught and handled in the BookingSystem class.
A) Creating the Exception Class
Define your own custom Exception subclass type VehicleException, which
represents an issue that occurs when attempting to record weight (for
oversized vehicles) or when attempting to calculate the booking fee for a
booking where the number or passengers or vehicle weight (for oversized
vehicles) has not yet been recorded in the BookingSystem.
This VehicleException type should allow an error message to be specified when
a new VehicleException object is created. No additional details need to be
recorded for this new VehicleException type.
Your exception class should be named VehicleException and it should be a sub-
class of the Java Exception class.
B) Generating Exceptions
Update the Vehicle class to instead generate and throw an exception with a
custom error message that indicates whether the exception was caused by one of
these two scenarios:
- invalid passenger numbers
- an invalid booking date.
Update the OversizedVehicle class to instead generate and throw an exception
with a custom error message that indicates when the vehicle is too tall to fit
on the ferry: - An oversized vehicle has a clearance height of greater than 3 meters.
C) Handling Exceptions
This VehicleExceptions should then be allowed to propagate back up to the
BookingSystem class (ie. the exception should not be caught locally within the
Vehicle or OversizedVehicle classes).
It will need to be caught and handled in an appropriate mannerin the
BookingSystem class (by displaying the error message contained within the
VehicleException object that has propagated up from the relevant method call).
Stage 6 - File Handling
This section of the program is designed to challenge and extend your problem
solving skills and is meant for the HD component of the assignment.
It is expected that you will design your own solution for this feature.
Your tutor can comment on your solution, but will not tell you how to write
this section of the assignment.
Your program should incorporate file handling functionality so that it writes
the details for each vehicle object currently in the Booking System out to
file when the program terminates (i.e. when the user selects the “Exit” option
in the menu).
The data that was previously written out to file should then be read back in
automatically when the program is started up again and the vehicle information
within should be used to create an appropriate set of Vehicle and
OversizedVehicle objects, which should be stored in the array or collection of
Vehicle references described in Stage 2 above.
If the vehicle data file is not found in the local folder then the program
should:
- 1.) First check for the presence of a backup file and if found use this backup file for loading the data.
- 2.) If loading from the backup file, display a message indicating that the data was loaded from a backup file.
- 3.) If no backup file is found, display a message indicating that no Vehicle data was loaded and continue on to the program menu without reconstructing any objects.
All vehicle data should be written out to and read in from (the same) text
file (containing the details for both Vehicle and OversizedVehicle objects in
the Booking System).
The format that you write vehicle data out in is entirely at your own
discretion as long as it is done to a text file.
One aspect of this task is to record any changes that have been made during
the previous run of the BookingSystem application, so your file handling
functionality must be able to handle the writing out and reading in of all
details for both types of vehicles in such a way that the state of the
BookingSystem at the point where the program was last exited is reconstructed
in full when the program is started up again.
You can make any changes or include any additional methods that you deem
necessary to the Vehicle / OversizedVehicle classes to facilitate the writing
out and reading in of details for both vehicle types to satisfy this part of
the specification.
Note that the program design described for the VehicleBooking,
OversizedVehicle and BookingSystem classes in stages 1 - 5 does not fully
support for what is required in this stage, so part of this task is
identifying what aspects need to be considered and designing / implementing a
solution accordingly to facilitate the writing out and reading in of details
for both booking types for this functionality.
Remember that you will still be required to adhere to basic object-oriented
programming principles (eg. encapsulation, information hiding, etc) when
designing your solution for this aspect of the program.