1.2 Encapsulation

Encapsulation

Encapsulation is the fundamental idea behind object-oriented programming. This concept can be found throughout all object-oriented languages. It was invented as a result of the need to model real-world problems. Even though procedural languages are extremely abstract implementations of a real-world model, they are mostly influenced by implementation issues rather than concerned about the business problem. As an example, with procedural code, variables (data) and functions (behavior) are separated. Because they are not "contained," the possibilities of reuse are limited.

Encapsulation models a problem according to a real-life situation. Variables and functions are logically bound together in what we call an object. Each object has a range of behavior and responsibilities. It also has to maintain its own set of data. Due to the self-contained nature of objects, they are easy to reuse.

Let's assume you want to create an application that takes care of seat reservations for a multiplex movie theater. In this case you'd want to handle reservations for each movie screen separately. In an object-oriented environment, you would most likely create an object for each screen. Each object would be able to count the number of available seats and might also be able to generate some statistics. The functionality and data are encapsulated in these objects.

Classes

Of course, it would be pretty annoying to code 15 different objects because you have 15 different screens. (It's a big movie theater.) After all, all these objects are basically the same. For this reason (well, not because of my theater example, actually ), the inventors of object-oriented technology came up with a concept called classes.

A class is basically a blueprint for an object. Once you have this blueprint, you can create as many objects out of each class as you want. Defining classes in Visual FoxPro is very easy and intuitive. There are several different ways to create classes, by the way. For now, we'll only look at the plain source code version. Later on we'll learn about visual class design.

To define our theater class in Visual FoxPro, we would write something like this:

DEFINE CLASS Screen AS Custom

ENDDEFINE

This is quite simple and doesn't require a lot of explanation. Only the "as custom" part might be a little confusing. But I'll get to that a little later.

Properties

Properties are variables that are encapsulated in an object (they belong to an object). Some other languages like C++ use the term attribute instead of property.

Other than the fact that properties live inside an object rather than in a program, they are a lot like variables. They can be of different data types (character, numeric, date, and so forth) and their values may change over time. Actually, properties are (just like variables) what I like to call semi-variants. That means that you can assign values of a certain type to a property, but you can always switch to a different type on the fly by simply assigning another value. And you can ask FoxPro about the current type using functions like Type() or VarType(). This is unlike other languages that store variables and properties as variants (such as VBScript) that don't have an exact defined type.

Defining properties is just as easy as defining a class. Here's the next incarnation of our theater sample with some assigned properties:

DEFINE CLASS Screen AS Custom

CurrentMovie = "The Sound Of Music"
AvailableSeats = 150
Date = {06/20/98}

ENDDEFINE

In this example we added three properties and assigned an initial value to each of them. In Visual FoxPro, there is no way to define standard properties without assigning a default value. In other words, standard properties are declared by assigning a value to them in the definition (this doesn't work at runtime). Of course there are some exceptions, but we won't worry about these right now.

Properties can even be arrays. Unlike regular properties, arrays cannot have initial values. Arrays are usually defined using the dimension keyword. Property arrays have initial dimensions, but they can always be redimensioned later on.

DEFINE CLASS Theater AS Custom

DIMENSION Screens(15,1)
ENDDEFINE

How to access properties

Because properties belong to objects, a couple of extra rules must be followed to access them. This is fairly easy. In the normal case, all we have to do is add the object's name before our property, and separate the two with a dot.

Let's assume we have an object called Screen1 (I know we do not yet know how to turn our classes into objects, but just go with me on this ). In this case we could access its properties like so:

Screen1.CurrentMovie = "Terminator"

Screen1.AvailableSeats = Screen1.AvailableSeats - 1

Screen1.Date = Date()

Note that this object is of the class Screen defined above. Object names and class names can be different and they probably should be. Remember that classes were invented so we wouldn't have to code each object individually. Of course, each object must have its unique name so that we can uniquely identify it.

Methods

Well, you already guessed it: Methods are functions that are encapsulated in an object. Defining them is just as easy as assigning properties. In order to make our Screen class complete, we add functions to make seat reservations:

DEFINE CLASS Screen AS Custom

CurrentMovie = "The Sound Of Music"
AvailableSeats = 150
Date = {01/20/98}

FUNCTION ReserveSeats( NumberOfSeats )
IF THIS.AvailableSeats - NumberOfSeats >= 0
THIS.AvailableSeats = THIS.AvailableSeats - NumberOfSeats
ELSE
MessageBox("Not enough seats available.")
ENDIF
RETURN
ENDFUNC

ENDDEFINE

In this example, we can pass the number of requested seats to the method ReserveSeats(), the method checks for the availability, and finally, the number of seats we requested is subtracted from the number of available seats. Of course, this is just a simple demo function, and there is a lot of room for enhancements. After all, it wouldn't make a lot of sense to make reservations without leaving your name, would it?

Accessing methods works the same way as accessing properties. Here's how we would make a reservation:

Screen1.ReserveSeats( 2 ) && Looks like my girlfriend joined in

THIS a first look

One keyword used in the example above has yet to be explained: THIS. Well, as mentioned above, object names are likely to be different from class names. As we have also seen, we need to know the object's name in order to access its properties and methods. Unfortunately, we do not know what the object name will be until the object is created. And even if we did know its name, we would limit ourselves to create one and only one object out of this class by using the real object name.

For this reason, each class/object knows about itself and grants itself access using the THIS keyword. So THIS.xxx always refers to the current object no matter what its real name is. The THIS keyword seems to be pretty common in object languages, although some, such as SmallTalk, use SELF instead.

How to draw classes

Figure 1 illustrates the notation I'll be using to draw classes in this book. It shows the above Screen class in Unified Modeling Language (UML) notation.

Figure 1. A simple class in UML notation.

Each class is drawn as a rectangle with the class name at the top. Underneath are all the properties and methods. These are optional. Sometimes I will draw a class as a simple rectangle with the name in it.

I'll discuss the UML notation in more detail in Chapter 12.



Advanced Object Oriented Programming with Visual FoxPro 6. 0
Advanced Object Oriented Programming with Visual FoxPro 6.0
ISBN: 0965509389
EAN: 2147483647
Year: 1998
Pages: 113
Authors: Markus Egger

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net