Expand
Minimize

Objects

Objects are the central idea behind OOP. The idea is quite simple.

An object is a bundle of variables and related methods.

A method is similar to a procedure; we'll come back to these later.

The basic idea behind an object is that of simulation. Most programs are written with very little reference to the real world objects the program is designed to work with; in object oriented methodology, a program should be written to simulate the states and activities of real world objects. This means that apart from looking at data structures when modelling an object, we must also look at methods associated with that object, in other words, functions that modify the objects attributes.

A few examples should help explain this concept. First, we turn to any student's favourite pastime...

Drink!

Say we want to write a program about a pint of beer. If we were writing this program in Modula-2, we could write something like this:

TYPE BeerType = RECORD
                    BeerName:       STRING;
                    VolumeInPints:  REAL;
                    Colour:         ColourType;
                    Proof:          REAL;
                    PintsNeededToGetYouDrunk: CARDINAL;
                    ...
                END;

Now lets say we want to initialise a pint of beer, and take a sip from it. In Modula-2, we might code this as:

VAR MyPint: BeerType;

BEGIN
    ...
    (* Initialise (i.e. buy) a pint: *)
    MyPint.BeerName := "Harp";
    MyPint.VolumeInPints := 1.00;
    ...
    ...
    (* Take a sip *)
    MyPint.VolumeInPints := MyPint.VolumeInPints - 0.1;
    ...

We have constructed this entire model based entirely on data types, that is we defined BeerType as a record structure, and gave that structure various names, e.g. Name. This is the norm for procedural programming.

This is however, not how we look at things when we want to program using objects. If you remember how we defined an object at the start of this section, you will remember that we must not only deal with data types, but we must also deal with methods.

A method is an operation which can modify an objects behaviour. In other words, it is something that will change an object by manipulating its variables.

This means that when we take a real world object, in this case a pint of beer, when we want to model it using computational objects, we not only look at the data structure that it consists of, but also all possible operations that we might want to perform on that data. For our example, we should also define the following methods associated with the BeerType object:

  • InitialiseBeer - this should allow us to give our beer a name, a volume, etc.
  • GetVolume - to see how much beer we have left!
  • Take_A_Sip - for lunchtime pints...
  • Take_A_Gulp - for quick pints...
  • Sink_Pint - for post exam pints...

There are loads more methods we could define - we might want a function GetBeerName to help us order another pint for example. Now, some definitions. An object variable is a single variable from an object's data structure, for example BeerName is one of BeerType's object variables. Now the important bit from this section:

Only an object's methods should modify its variables

There are a few exceptions, but we'll cover them much later. What this means in our example is that unlike the Modula code, we cannot directly modify BeerType's variables - we cannot set BeerName to "Guinness" directly. We must use the object's methods to do this. In practice, what this means is that we must think very carefully when we define methods. Say in the above example we discover when writing the main program that we need to be able to take a drink of arbitrary size; we cannot do this with the above definition, we can only take a sip, a gulp etc. We must go back and define a new method associated with BeerType, say Take_Drink which will take a parameter representing the amount of beer we wish to drink.

Another Example

We'll now deal with a real-life example which will help us understand some more object concepts. We will design an object to emulate a counter.

A counter is a variable in a program that is used to hold a value. If you don't know that then you shouldn't be reading this! To make things very simple, we'll assume that our counter has only three operations associated with it:

  • Initialising the counter to a value
  • Incrementing the counter by one
  • Getting the current value of the counter

So, when we come to implement the above using objects we will define three methods that do the above.

You may be thinking that we could implement this very simply in Modula-2 using definition and implementation modules obtaining the same results as if we used an object oriented language. Well, we nearly can:

DEFINITION MODULE Counter;

PROCEDURE InitialiseCounter(InitialValue: INTEGER);

PROCEDURE IncrementCounter;

PROCEDURE GetCounterValue(): INTEGER;

END Counter.


IMPLEMENTATION MODULE Counter;

VAR MyCounter: INTEGER;

PROCEDURE InitialiseCounter(InitialValue: INTEGER);
BEGIN
    MyCounter := InitialValue;
END InitialiseCounter;

PROCEDURE IncrementCounter;
BEGIN
    INC(MyCounter);
END IncrementCounter;

PROCEDURE GetCounterValue(): INTEGER;
BEGIN
    RETURN MyCounter;
END GetCounterValue;

BEGIN
    MyCounter := 0;
END Counter.

Because Modula-2 is not object oriented, this will only satisfy one of the requirements for an object oriented language - encapsulation. This simply means that we have implemented information hiding, i.e. we cannot directly access MyCounter from any module that imports Counter. But being object oriented means a lot more than just encapsulation, as we'll see...

Next: Classes.


2011 Contact