2.2 Structure of Classes and Objects


 

To use objects of an existing class it is necessary to understand something of their structure and operation, just as when learning to drive a car it is useful to understand something about the car's structure - where the driver sits and where the ignition key goes - and the car's operation - what the steering wheel does, what the accelerator pedal does, etc.

Public vs. Private Parts

For a programmer (re)using an existing class, the key element of the class's structure is its public interface. The class's public interface defines the behavior of all objects created from this class definition. The public interface contains a set of methods (also called procedures, member functions, or operations) that can be used to manipulate the objects created from this class. The only way to manipulate an object is by using the methods defined in the public interface of the class from which the object was created.

A class, and any object created from it, also contains a private (hidden, internal, encapsulated) implementation. The user of an object has no concern with how the object is implemented, just as the driver of a car need not have any concern with how the engine is constructed. The internal details of an object's implementation can be ignored by the user of the object.

In C++ the public and private portions of a class are denoted by keywords as shown in the following:

class Frame {
  private:
         // encapsulated implementation goes here
  public:
         // public interface goes here
 }; 

The separation of the public interface from the private implementation is a major aspect of object-oriented programming. The public interface defines a contract between the object's implementor and the object's user. The contract specifies what service the implementor has agreed to provide and limits the ways in which the user is allowed to manipulate the object.

The separation of public interface from private implementation has several advantages:

  • It promotes understanding and reuse by reducing the amount of information confronting the user of an object
  • It increases implementation flexibility by allowing the implementor to change the implementation (say to a more efficient one) so that in future programs the object looks and acts the same to the object's user, who is unaware that a different implementation is involved,
  • It eases the difficult task of debugging by providing a boundary that can be used to isolate the source of an error
  • It improves the overall design of the system by allowing it to be presented and understood as a collection of public interfaces

These benefits will be understood more deeply as the ideas of object-oriented programming are developed and as experience is gained in working with and building object-oriented systems.

Methods in the Public Interface

The public interface may (and usually does) contain three different kinds of methods:

  • Contructors: methods that define how the object is initialized. There commonly are several constructors, allowing the object to be initialized in different ways. A constructor is invoked implicitly when an object is created. An object cannot be created without a constructor being invoked.
  • A destructor: there is only one such method in each class that is invoked implicitly when an object is destroyed.
  • Behavioral methods: these define how the object behaves or can be manipulated during its lifetime. These methods are often subdivided into:
    • accessor/interrogator methods that return information about the state of the object but do not change the state of the object, and
    • manipulator/mutator methods that (potentially) change the state of the object.

If no constructor or destructor is defined, a default one is provided. The default constructor and default destructor do nothing.

Note that constructors and destructors are invoked implicitly. That is, they are invoked automatically as a result of the execution of some statement. For example, a constructor is invoked implicitly when a declared object is created; the constructor is invoked as a result of the declaration statement. Constructors and destructors are never invoked explicitly by the programmer's code.

An Abstraction for a GUI Window

The Frame class is the first of several abstractions of a graphical user-interface (GUI) window. A GUI window has numerous capabilities as shown in the figure below. A real-world GUI window has operations that can be performed on it to affect its placement and size, is capable of displaying a wide range of information-bearing elements (graphical, iconic, textual), and affords a means of interacting with the user through control elements (buttons, menus, etc.). To avoid confronting all of these powerful capabilities in the first class being studied, a series of simpler abstractions will be shown. The figure below shows the first of these simpler abstractions.

Abstraction of a GUI Window

Consistent with the ideas of mapping an abstraction to a class, the first version of the Frame class is defined as shown below.

The Frame Class
class Frame {                   // Version 1
 private:
          // encapsulated data  goes here
 public:
        Frame      (char *name, int initXCoord, int initYCoord, 
                                int initWidth,  int initHeight);
   void Resize     (int newHeight, int newWidth  );
   void MoveTo     (int newXCoord, int newYCoord );
   int  IsNamed    (char *name);
   void Clear      ();
   void DrawText   (char *text, int atX, int atY);
   void DrawLine   (int fromX, int fromY, int toX, int toY);
   void DrawCircle (int centerX, int centerY, int radius);
       ~Frame   ();
};

In this example, the constructor method has the same name as the name of the class (Frame). This constructor requires five arguments: the name to be associated with the Frame; the initial (x,y) coordinates of the Frame's upper left corner, given by the pair (initXCoord, initYCoord); and the Frame's initial dimensions (width and height). The last method, named ~Frame, is the destructor; placed here are any actions that the must be taken when the Frame object is destroyed. The IsNamed method is an accessor method that allows the program to determine if the name of the Frame matches the method's input argument. All other methods are manipulator methods. The two methods Resize and MoveTo provide operations to relocate the Frame on the screen and to change its size. The DrawLine and DrawCircle methods allow simple graphical shapes to be drawn in the Frame. The method DrawText allows text to be written into the Frame. The upper left-hand corner of the area where the text is written within the Frame is specified by the (atX, atY) coordinates. The Clear method erases all text and graphics from the Frame. A real Frame class would have more methods, but these suffice for a number of interesting examples.

Notice in the above definition of the Frame class that no executable code is given for any of the methods. This is in keeping with the desire to hide all of the implementation details of an object - the user of the class cares only about what operations are defined, not how these operations are implemented. The creator of the class must, of course, write the code for these methods and provide the other private data as well. We will see later how this is done.

Tasks

  1. Illustrate the difference between the public interface and the private implementation in the following ordinary objects:
    • a personal computer
    • a telephone
    • a radio

    For each ordinary object identify several operations in its public interface and name one or more things that are probably in its private implementation.

  2. For one of the ordinary objects in the last question show how the public vs. private separation results in the advantages cited above (i.e, reuse, flexibility, debugging, design).
  3. Write a class definition (without the private section) for a "stack of integers" class.
  4. Write a class definition (without the private section) for a "file of characters" class.
  5. Write a variation of the Frame class (version 1) that moves the Frame by a relative amount (i.e., up or down a given number of units and left or right a given number of units).

  6. Write a variation of the Frame class (version 1) that changes the size of the Frame by a fractional amount (e.g., makes it 50 percent bigger or 50 percent smaller).

  7. Write a variation of the Frame class (version 1) that allows rectangles and triangles to be drawn in the Frame.

 




©1998 Prentice-Hall, Inc.
A Simon & Schuster Company
Upper Saddle River, New Jersey 07458

Legal Statement