The objective of this lab is to review and use object-oriented principles to design and implement classes to meet specific purposes
Consider the following class diagram illustrating the relationships between various types of vehicles:
You are to implement a form of this class diagram. Your implementation must
allow creating instances
of Car
, Pickup
, Dumptruck
,
and Convertible
, but not Vehicle
. (See
the Wikipedia pages
on pickups
and dump trucks for
how we are using the terms.)
For this
diagram, treat the relationship between Vehicle
and other classes
as any type of inheritance. Class Vehicle
can be an interface, an
abstract class, or even a regular class. You will pick one and justify your choice.
All vehicles must support the following operations:
start
stop
goForward
goBackward
In addition,
Your classes must be written so
that Dumptruck
, Pickup
,
and certain convertibles can plow snow. You might think that
convertibles never plow snow, but the image to the right shows
otherwise. General Car
objects cannot plow
snow. Any vehicle which can plow snow must be able to
respond to raisePlow
and lowerPlow
and must have
the attribute plowWidth
. In addition, your design must meet
the constraints that convertibles are a type of car (they must "be a" car),
dump trucks are not a type of car, and plows on convertibles are
optional (that is, some convertibles have plows and others do
not). Finally, create a class for plows, or at least for all vehicle types
that include a plow, so the plow operations are not repeated in multiple
classes.
You must use the class hierarchy to enforce these restrictions. All errors
such as trying to call raisePlow
on a general Car
should result in compiler errors. (A common alternative implementation is
to throw a run-time error on applying an operation to an object that does
not support it. Do not depend on run-time errors for these checks.) This
means you will need to introduce abstract classes and interfaces that
ensure a particular vehicle class has exactly the correct operations. This
also means you will need separate classes for convertibles which support
plows and those which do not.
You are to build an implementation for this system using the object-oriented design principles that you learned in SE/CS 1011 and SE/CS 1021. In particular, you should eliminate duplicated code ("don't repeat yourself"), use interfaces and abstract classes as appropriate, leverage inheritance where appropriate, ensure methods are small, etc. Note that the above diagram does not necessarily reflect a good design! You will need to add your own classes and reorganize the inheritance to improve on the design.
To make the system easier to debug and understand, add a name
attribute to all classes that can have instances (at least) so
that each instance can be given a unique name such as `Tommy the Truck' and
`LoveBug'. You will use this name in the driver code (see below)
Use Enterprise Architect to draw a new class model for your revised system. Your diagram should capture your improvements to the design. Do not list constructors, getters, or setters. Also, ensure that parameter types and return types are not displayed:
You need to open the properties box twice because sometimes changing both settings at the same time fails. Since this project will have just a single package, showing the package is optional.
In addition, write a VehicleApp
containing a main
that
creates various objects and calls all of their methods. This includes
calling the name
in key places method so it is clear which
vehicle is doing which operations. The methods shown
in the above diagram will simply state that a certain action is being
called for a given vehicle. For instance, the raisePlow
action
on the LoveBug would state that the LoveBug is raising the plow. This
very simple test-bed main will ensure that all of the above methods are
fully implemented. Write your implementation so it tests
the Car
class, then the convertible classes,
then the Pickup
class, and finally
the DumpTruck
class (in that order!). Do not use
casting (e.g. (DumpTruck)car
) in your solution.
You should explicitly check that calling raisePlow()
and lowerPlow()
on some vehicles causes a compilation error and
that calling raiseRoof()
and lowerRoof()
on any vehicle
other than a Convertible
causes a compilation error. Once you have
checked these do create compilation errors, comment out the code and leave
it in your system so the delivered system builds. This is important for
speedy demos.
Place all of your code in a single package using the declaration
package username;where
username
is your own login name (without
any @msoe.edu
). Do not create nested packages for this assignment.
Following directions is an important part of the assignment.
Things to consider:
raisePlow
for each type of vehicle. It
might be just a line or two savings here, but imagine supporting yet
more types of vehicles or adding the code to support the hardware. Your
solution should scale appropriately.
implements
, and association ("has-a").
Using the correct arrow for each is important.
Your instructor will describe how to submit your code and give you deadlines. You must submit the following:
VehicleApp
on your class diagram. This
class just exercises the API you are building, and the goal for the
diagram is to document the API.
Note that this is an individual assignment, though you are allowed to discuss it in general terms with other students.