Expand
Minimize

Classes

Say we wanted to extend the counter example discussed previously. Perhaps in our Modula-2 program we need three counters. We could define an array of MyCounter and work through that. Or say we needed up to 1000 counters. Then we could also declare an array, but that would waste a lot of memory if we only used a few counters. Perhaps if we needed an infinite amount of counters we could put them in a linked list and allocate memory as required.

The point of all this is that we are talking in terms of data structures; all of the above discussion has nothing to do with the behaviour of the counter itself. When programming with objects we can ignore anything not directly concerning the behaviour or state of an object; we instead turn our attention to classes.

A class is a blueprint for an object.

What this basically means is that we provide a blueprint, or an outline of an object. This blueprint is valid whether we have one or one thousand such objects. A class does not represent an object; it represents all the information a typical object should have as well as all the methods it should have. A class can be considered to be an extremely extended TYPE declaration, since not only are variables held but methods too.

C++

As an example, lets give the C++ class definition for our counter object.

class Counter  {

    private:
        int MyCounter

    public:
        Counter()  {
            MyCounter = 0;
        }

        void InitialiseCounter(int value)  {
            MyCounter = value;
        }

        void IncrementCounter()  {
            MyCounter++;
        }

        int GetCounterValue()  {
            return (MyCounter);
        }
}

A lot to go through for this little example. You really need to understand the fundamentals of C before the example will make any sense.

  • In the private section, all the objects variables should be placed. These define the state of the object. As the name suggests, the variables are going to be private, that is they cannot be accessed from outside the class declaration. This is encapsulation.
  • The public section contains all the object's methods. These methods, as the name suggests, can be accessed outside the class declaration. The methods are the only means of communication with the object.
  • The methods are implemented as C++ functions or procedures; the three methods should be easy to understand.
  • All class definitions should also have one public method that has the same name as the class itself, in this case Counter. This method is called the class constructor, and will be explained soon.
  • Functions and procedures can also be placed in the private section; these will not be accessible to the outside world but only within the class declaration. This can be used to provide support routines to the public routines.

Instantiation

This is an awful big word for a powerfully simple concept. All we have done so far is to create a class, i.e. a specification for our object; we have not created our object yet. To create an object that simulates a counter in C++ then, all we have to do is declare in our main program:

Counter i;

Although this seems just like an ordinary variable declaration, this is much more. The variable i now represents an instance of the counter type; a counter object. We can now communicate with this object by calling its methods, for example we can set the counter to the value '50' by calling i.InitialiseCounter(50);. We can increment the counter - i.IncrementCounter(); - and we can get the counter value - int value = i.GetCounterValue();.

When we first instantiate an object (i.e. when we first declare, or create it), the class constructor is called. The class constructor is the method with the same name as the class definition. This method should contain any start-up code for the object; any initialisation of object variables should appear within this method. In the counter example, whenever we create a new counter object, the first thing that happens to the object is that the variable MyCounter is initialised to zero.

Remember the question posed at the very start? The power of objects starts to kick in now. Say we require another counter within our program. All we have to do is declare a new object, say:

Counter j;

Although the new counter shares the same blueprint as the previous object, it shares none of the same data. What this means is that i and j are two distinct objects, each with their own separate values. We can increment them independently, for example. Should we need 1000 counter objects we could declare an array of counter objects:

Counter loads[1000];

and then initialize one of them using a call such as loads[321].InitialiseCounter();.

Java

The equivalent Java class definition for the counter example follows. It is remarkably similar to the C++ definition, and differs only in syntax.

class Counter extends Object  {

    private int MyCounter;

    Counter()  {
        MyCounter = 0;
    }

    public void InitialiseCounter(int value)  {
        MyCounter = value;
    }

    public void IncrementCounter(void)  {
        MyCounter++;
    }

    public int GetCounterValue(void)  {
        return (MyCounter);
    }
}

A few brief notes about the differences:

  • All new classes must be defined with the extension extends Object. This defines the superclass; this will be dealt with in the next section.
  • There are no public or private sections, instead all variables and methods are prefixed with the appropriate public or private qualifier.
  • The class constructor definition remains the same.

Instantiating objects in Java is slightly different; objects are declared differently:

Counter i;

i = new Counter();

Basically we define a variable to reference the object in the first line. Then we actually create an instance of the object by a call to new in the second line. Accessing object methods is done in the exact same way in Java as in C++.

Why Bother?

The process of designing and programming objects seems very cumbersome, so why bother? Well, it's difficult to see from such a small example, but for larger projects, OOP techniques allow a great deal of flexibility. OOP is used for the following reasons.

  • Encapsulation: in our example we cannot alter the value of the counter other than by incrementing it or setting it to a initial value. This drastically helps with understanding of the code and eliminating potential bugs.
  • Modularity: Different programmers or teams can work on different independent objects.
  • Inheritance: this is covered in the next section.

Next: Inheritance.


2011 Contact