Designing a Class Hierarchy
Consider an
abstract class that serves as a file interface. It declares the functions open(), close(), read() and write() as
pure virtual:
class File
{
public:
virtual int open(const string & filename)=0;
virtual int close(const string & filename)=0;
//
virtual ~File()=0; // remember to add a pure virtual dtor
};
Classes derived from File implement the pure virtual functions and provide additional operations. For example, a DiskFile class may add the flush() and defragment() operations:
class DiskFile: public File
{
public:
int open(const string & filename);
// implementation of other pure virtual functions
// specialized operations
virtual int flush();
virtual int defragment();
};
You then derive additional classes from DiskFile such as TextFile and MediaFile, for files that contain audio and video clips:
class TextFile: public DiskFile
{
//
int sort_by_words();
};
class MediaFile: public DiskFile
{
//..
};
The use of such a hierarchy enables you to create
polymorphic objects:
File *pfile; // static type of *pfile is File
if(some_condition)
pfile = new TextFile; //dynamic type is TextFile
else
pfile = new DiskFile; //dynamic type is DiskFile
Suppose you're developing a GUI-based file manager that displays files as icons. When you pass your mouse over such an icon and click, the file manager opens a menu that adjusts itself dynamically according to the marked file. The menu lists a set of operations such as "copy", "paste," and "open." In addition, it displays specialized operations for the particular file. Thus, for a text file, it adds the "edit" operation whereas for a multimedia file it displays the "play" operation instead.