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...
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
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
There are loads more methods we could define - we might
want a function
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
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:
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
one of the requirements for an object oriented
encapsulation. This simply means that we have implemented
information hiding, i.e. we cannot directly access