Suppose you need to write an inventory control system for automobile parts.
Write a UML class diagram with a base class named AutoPart and some subclasses like, EnginePart, BodyPart, Accessory, etc. and concrete part classes like Alternator, Fender, Radiator, SeatBelt, etc.
Write (but do not implement) class definitions for your classes. What kinds of base class functions will be needed?
How will you guarantee that only the concrete part classes can be instantiated?
The classes in Figure 6.9 are intended to help organize the film collection in the college library.
Implement the Film
classes. Make sure that the constructors
have sufficient parameters to initialize all data members. We suggest enum
types FilmTypes
(Action, Comedy,
SciFi, ...) and MPAARatings
(G, PG, PG-13, ...) for use in the
Entertainment
class.
Implement the FilmList
class as a container of Film
pointers. Make sure that the addFilm()
function does not permit the same Film to be added more
than once.
Is it possible to use base class functions such as contains()
or indexOf()
here?
Write client code to test these classes. Put a mixture of Entertainment
and Educational
films
into the FilmList
and exercise all the member functions.
Having a container of pointers raises the question of how to destroy it. If you simply "do the right
thing" and define a FilmList
destructor that visits each of its pointers
and deletes it, you must then worry about client code that contains a function with a FilmList
value parameter. Recall that each value parameter causes a copy of
the corresponding argument to be made. That copy is destroyed when the function returns. How should
you deal with copying and destroying FilmList
objects?
The FilmList
class enables you to exploit polymorphism but exposes the
Film
pointers to client code. So far, this design violates our earlier
warning regarding the use of pointers. In general, pointers must be hidden from client code. We
discuss an approach to this problem in Section 16.3.
Refine our solution to Extended Example: A Simple Library by adding a LibraryUI
class that handles the interactions with the user as suggested by
the following UML diagram.
When you add that class, you should use the client code in Example 6.43 to test your system.
Example 6.43. src/pointer-container/libraryClient-v2.cpp
#include "libraryui.h" #include "library.h" bool saved(false); int main() { Library lib; LibraryUI libui(&lib); while(1) { switch(libui.nextTask()) { case LibraryUI::READ: libui.read(); saved = false; break; case LibraryUI::ADD: libui.enterData(); saved = false; break; case LibraryUI::FIND: libui.find(); break; case LibraryUI::REMOVE: libui.remove(); saved = false; break; case LibraryUI::SAVE: libui.save(); saved = true; break; case LibraryUI::LIST: libui.list(); break; case LibraryUI::QUIT: libui.prepareToQuit(saved); break; default: break; } } }
Refine your solution to 3 so that each class has its own corresponding UI class, as suggested by the following UML diagram.
Change the implementation of the Library
class so
that it is derived from QMap<QString, RefItem*>
where the QString key is the ISBN
code.
[ fromfile: inheritance-intro.xml id: ex-inheritance ]
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |