3.2 Objects as Parameters
The examples that follow make use of two new classes. In the original
definition of the Frame class the location and shape of the frame were
described by four integer values. Both of these concepts, however, can
be captured in classes as follows:
class Location { // Version 1
private:
// encapsulated implementation goes here
public:
Location(int x, int y); // specific location
Location(); // default location
int Xcoord(); // return x-axis coordinate
int Ycoord(); // return y-axis coordinate
};
class Shape { // Version 1
private:
// encapsulated implementation goes here
public:
Shape(int width, int height); // specific shape
Shape(); // default shape
int Height(); // return height
int Width(); // return width
};
The methods Xcoord, Ycoord in the Location class and Height and Width in the
Shape class are often called "accessor" methods because they allow you to
access, albeit indirectly, some information about the state of the object.
These new class can be used as follows:
Location nearTop(20, 20), nearCenter(500, 500);
Shape smallSquare(50, 50);
Shape largeSquare(500, 500);
These two classes have two advantages (five more will be seen
shortly). First, they capture the concept of "location" and
"shape". This is largely what "real" object-oriented programming is
about - building classes that capture the concepts of some
application. A good class need not be one that has an "important
looking" interface. The Location and Shape classes are modest ones
that cleanly capture a simple, but useful, concept. Second, the
declarations above show that named objects can convey useful
information to the reader about the intention of the programmer. The
name "largeSquare" is more suggestive about the intention to have a
window that is large and square than are the two integers 500 and 500
used in a parameter list with two other integers and one or more other
values.
The Frame class can now be redefined to use the definitions of Shape and
Location as follows:
class Frame { // Version 3
private:
// encapsulated implementation goes here
public:
Frame(Location p, Shape s); // exact description
Frame(Shape s, Location p); // exact description
Frame(Location p); // default shape
Frame(Shape s); // default location
Frame(); // all defaults;
void MoveTo(Location newLocation); // move the window
void Resize(Shape newShape); // change shape
void Resize(float factor); // grow/shrink by factor
};
The third advange of defining the Shape and Location classes is seen in the
first two overload constructors. Since Shape and Postion are distinguished
classes it is possible to define constructors that take them in either
order. This cannot be done when the shape and location information is
represented by four integer values. The fourth advantage is seen
in the overloaded constructor "Frame(Shape s);". Such a constructor
did not (and could not) exist in the earlier version (Version 2) of
the Frame class. When the location and shape information is
represented as four integers, what does a constructor with only two
integers mean? Depending on how the four arguments are ordered it
means either that the shape is missing or the location is missing, but
it cannot mean both! However, both overloading are possible by
introducing different classes that distinguish the two integers that
are the shape from the two integers that are the location.
Frame objects can be created as follows:
Frame smallTop (nearTop, smallSquare);
Frame largeCenter (nearCenter, largeSquare);
Frame someWhere (largeSquare);
Frame someSize (nearCenter);
Frame anyKind;
These declaration of Frame objects illustrate the last three advantages of
the Shape and Location classes. Fifth, the declarations are much more
readable with the Shape and Location classes than without. Sixth, the
Shape and Location objects (e.g., largeSquare and nearCenter) can be
reused, avoiding the addition programming effort of remembering the exact
coordinates of the "near to the center" point. Seventh, by changing the
declaration of the Shape and Location objects (e.g., nearTop) the declarations
of the Frames will then be adjusted accordingly. It is not necessary to go
through the code looking for all the declaration of Frame objects and
changing their integer parameters.
The Location class has uses beyond those for which it was immediately conceived.
Since the Location class captures a reasonably abstract notion - a point in a
two dimensional coordinate system - it may be useful anywhere such a coordinate
system appears. For example, just as the Location class helps to record "where on
the screen should a window be placed" it can also be used by other interface
items to record "where within a window should an icon be placed".
The Message class is a simple user interface element that can be placed at a location
within a window. The definition of this class is:
class Message {
private:
// encapsulated implementation goes here
public:
Message(char* text, Location p); // Message with text at Location p
Message(char* text); // Message with text a default Location
~Message(); // delete message
};
The Message class uses the Location class in its first constructor to determine where
within a window the text of the message is to appear.
The Frame class is extended again to provide a means for placing a Message object in
a window. The extended definition is:
class Frame { // Version 4
private:
// encapsulated implementation goes here
public:
Frame(Location p, Shape s); // exact description
Frame(Shape s, Location p); // exact description
Frame(Location p); // default shape
Frame(Shape s); // default location
Frame(); // all defaults;
void MoveTo(Location newLocation); // move the window
void Resize(Shape newShape); // change shape
void Resize(float factor); // grow/shrink by factor
void Display(Message msg); // show msg in window
};
The following code shows how the Location class is used in creating a Frame object
and a Message object:
//Declarations
Location windowLocation(50, 50);
Location msgLocation(10, 10);
Frame window(windowLocation, Shape(100, 200);
Message msg("Hello World!", msgLocation);
// code
window.Display(msg);
| Exercises |
- Give at least two other good names that could be used for the Shape
class.
- Give at least two other good names that could be used for the Location
class.
- Give at least two other good names that could be used for the Message
class.
- Give the declarations of at least four Location objects that are on the
top and left-hand side of the display.
- Give the declarations of at least four Shape objects that are thin
rectangles that are short or long in length.
- Give the declarations or at least four Frame objects that use different
combinations of the Location and Shape objects defined in the last two
questions.
- Draw a picture of a screen showing how the Frame object declared in the
last question would appear on the screen. Label each Frame in the
picture with the name of the object that it represents.
- Write a program that creates a 200 by 200 size window near the middle of
the screen with your complete name displayed near the middle of that
window.
-
Write a program that creates a 200 by 200 size window near the middle of
the screen with your first name centered at the top of the window and your
last name centered at the bottom of the window.
Last updated: August 21, 1995 / kafura@cs.vt.edu