Lab-06 VehicleFleet
2. Additional Description
We have a VehicleFleet
administration app, holding items of Car
, Truck
and Trailer
. All of them are specializations of abstract Vehicle
.
Every Vehicle
has a unique InventoryCode
as soon as it becomes included into the fleet. Before that the InventoryCode
can be null
or is set at some moment. After setting it is not changeable – the setter has to throw a ChangeInvtCodeException
.
The invtCodeTxt
consists of 3 Letters labelling the kind
(Car → CAR, Truck → TRU, Trailer → TRA) and a 5-digits number, which is automatically incremented after being "consumed" (done within generate4kind()
).
Ensure the number is filled with '0’s if less than 5 digits (see example below).
The inventoryCode Objects (Class InventoryCode
) hold the invtCodeTxt
and some "intelligence" via methods:
-
Static factory method
InventoryCode generate4kind(String invtPrefix) throws …
… calls static methodvoid checkValidKindPrefix(String invtPrefix)
. The latter does the checks for validity (one of 'CAR', 'TRU', 'TRA') and throws aBadInvtKindPrefixException
if needed (does nothing otherwise!). -
Static method
void checkValid(String invtCodeTxt)
is provided to check a given complete invtCodeTxt for validity. ThrowsBadInvtCodeException
in case of invalidity: invalid prefix, rest not exactly 5 digits. -
Instance method
void checkValidFor(Vehicle vehicle)
is able to check if a given InventoryCode object is suitable to be used for the kind of the given vehicle (parameter).It uses:
if (vehicle instanceof Car car) { // prefix 'CAR', …}
. -
Method
equals(..)
of the key objects is used extensively in collections – e.g. Map-methodsget(..)
containsKey(..)
,remove(..)
, … . As soon as we use hashes behind the scenes,hashCode()
is used too and it is EXTREMELY important that it’s definition is consistent withequals(..)
, since these work together then. So auto-generation (Menu Source → generate hashCode() and equals() …) in Eclipse/IntelliJ should be used.
Method add(..)
has to set the InventoryCode value invtCode
if it is null to ensure the Vehicle
has the needed Map key attribute.
To find out if an object is member of a certain class or interface, use:
// ...
if (someObj instanceof SomeClassOrIface) {
ScomeClassOrIface scoi = (ScomeClassOrIface) someObj; // obsolete in Java16
scoi.someMethod();
//...
}
// or better since Java 16:
if (someObj instanceof SomeClassOrIface scoi) {
scoi.someMethod();
// ...
}
// ...
public class InventoryPrefix {
// ...
public static InventoryCode generate4kind(String kindPrefix)
throws BadInvtKindPrefixException {
checkValidKindPrefix(kindPrefix);
// %05d ensures 5 digits are here, missing ones filled with '0's:
return new InventoryCode("%s%05d".formatted(kindPrefix, nextInvtNr++));
}
public static void checkValid(String invtCodeTxt) throws BadInvtCodeException {
// ...
}
// ...
}
In VehicleFleet
the Exceptions BadInvtKindPrefixException
, BadParamException
and ChangeInvtCodeException
can only happen if the app logic is incorrect - so we catch these and rethrow an AppBugRtException("InvtCode Bug? %s".formatted(invtCode), ex)
, giving the original exception as second param ex
.
Method VehicleFleet#checkValidFor(Vehicle vehicle)
has to be called before the InventoryCode is added to the Vehicle - cound be done in setter of Vehicle or externally within the VehicleFleet add(..) method. Should throw BadInvtKindPrefixException
, if the wrong prefix for the given vehicle is set.
The Car
, Truck
and Trailer
classes need a overridden toString()
which has to use the one of the superclass as the first part. Subclass specific attributes have to be added behind.
Format should be chosen in a way that extending is possible – so let away any brackets! To use dynamic class name creation use
this.getClass().getSimpleName()
which provides the real class instead of a statically written one!
Do some simple testing e.g. within a main method or by a separate test class.