SE2811 Software Component Design
Lab 1: Inheritance

The objective of this lab is to review and use object-oriented principles to design and implement classes to meet specific purposes

Assignment

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:

In addition, all vehicles must have a number of wheels and a weight attributes. Note there are other methods and attributes that are implied by the diagram; you must be able to set these values (possibly through extra parameters in constructors) and have getter (accessor) methods to return their value.

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:

  1. Right click on the class model in EA
  2. Select Properties...
  3. Click on Features
  4. Clear Show Operation Return Type
  5. Click OK
  6. Reopen the Properties and navigate to Features
  7. Set Show Parameter Detail to None
  8. Click OK

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:

Submission

Your instructor will describe how to submit your code and give you deadlines. You must submit the following:

Your instructor may have additional requirements.

Note that this is an individual assignment, though you are allowed to discuss it in general terms with other students.