PreviousRequirements-based Vocabulary Tutorial (UNIX) Class ProgramsNext"

Chapter 19: Using Objects in Programs

This chapter describes how you can use objects in your programs. The same rules apply whether the program you write is an Object COBOL class, or a procedural COBOL program in which you want to use Object COBOL objects.

19.1 Overview

Objects can be used by an application which is not itself object-oriented. This chapter describes how you can add objects to a program and send messages to them. All the information in this chapter applies equally to Object COBOL class programs and to procedural programs which use objects.

This chapter uses examples of code to illustrate points. For the full syntax definitions, see your Language Reference.

Programs which use objects all have certain features in common:

Generally, a program which uses objects will send a message to one or more class objects to create the instance objects it requires. For each instance object created, you must declare an object reference to hold the object handle, although you may overwrite the object handle in an object reference with a new one if you have finished with it. When a program has finished with an object, it should destroy it (by sending it the "finalize" message).

19.2 Registering Classes

Before you can use an Object COBOL class, you must register it. To do this, you must declare it in the Class-Control paragraph of every program which uses it. This binds the name of the class to the executable file for the class program.

It also makes the name of the class available to your program as an Object Reference data item with the same name as the class. This enables you to send messages to the class object.

The code below shows class registration for classes CharacterArray and myClass:

class-control.
    CharacterArray is class "chararry"
    myClass is class "myclass"
    .

The filename is in quotes after the IS CLASS clause. The spelling and case of a filename in Class-Control must match in all the Class-Control paragraphs which refers to it. You are strongly advised to adopt a convention of specifying all filenames in Class-Control in lower-case. Matching is case-sensitive to keep source-code compatibility between case-insensitive and case-sensitive operating systems.

19.3 Using Object References

A data item of type object reference can hold a handle to a class or instance object. In this release of Object COBOL, object references are untyped, so the same data item can hold an object reference for any class or instance object. That is, there is no distinction between the type of object reference declared to hold an instance of one class or another.

19.3.1 Declaring Object References

You need to declare data items of type OBJECT REFERENCE to hold handles to any objects you will be using.

For example:

01  anItem           object reference.

You also require object references for any class you are going to use in your program. These are declared automatically when you list your classes in the Class-Control Section.

19.3.2 Manipulating Object References

The only operations you can use on object references are:

No other operations are valid, because the object reference only contains a handle to an object. To change or interrogate an object's internal state, you have to send messages to it.

If you clear all references to a particular object (with SET), you will be unable to send that object any more messages. In particular, you will not be able to destroy that object and deallocate its storage (see the section Destroying Objects).

19.4 Message Sending

You send a message to an object to make it execute a method. The method executed has an identifier which matches the message.

If an object does not understand a message, it is passed up the method inheritance chain until it is recognized and executed (see the section Method Inheritance Chain in the chapter Class Programs for more information). The method inheritance chain is not a consideration if you are the user of the object; it is part of the object's implementation details.

You send a message by using the INVOKE verb. For example:

invoke myClass "new" returning myObject

This sends message "new" to myClass; in this example myClass is an object reference referring to the class declared in the example in the previous section. The target of an invoke is always an object reference. Using and returning parameters are optional, and follow the same rules as a COBOL CALL statement.

You do not have to use a literal for the message name. You can also put a message name into a pic x(n) data item. For example:

move "new " to aMessage
...
invoke myClass aMessage returning myObject

The data item used to store the message must be large enough to allow at least one space at the end of the message name. The run-time system needs the space to be able to find the end of the message name.

The results are unpredictable if you send a message and use the same variable for sending a parameter and returning a result. For example, do not code:

invoke myObject "add" using aValue returning aValue

19.5 Create a New Object Instance

When you create a new object, the run-time system allocates an object handle, and storage for the variables declared in the Object-Storage Section. Classes either provide their own methods for creating new object instances, or inherit them from a superclass.

Method "new" is implemented in class Base (part of the supplied Class Library) to create an instance of a single object. Send the message to a class and provide a variable to receive the object reference.

For example:

 working-storage section.
 01  anObject           object reference.
   ...
 procedure division.
    ...
    invoke aClass "new" returning anObject

In this example, aClass returns a handle to a new instance of itself in object reference anObject. Some Class Library classes implement a version of "new" which expects one or more parameters for initialization. Some classes, for example Window, implement a "new" method which sends the newly created object the "initialize" message.

Consult the on-line Class Library Reference to check the interface to the "new" method for a class you want to use. Object creation methods are always class methods. Not all types of objects are created with the "new" message; for example the collection objects are created by "ofReferences" and "ofValues" methods.

19.6 Destroying Objects

When an application has finished with an object it should destroy it, freeing the memory it uses. This is because Object COBOL does not yet implement automatic garbage collection.

The following sections explain object destruction in more detail:

19.6.1 Object Destruction Methods

To destroy an object, send it the "Finalize" message. For example:

invoke anObject "finalize" returning anObject

The "finalize" method is implemented in the Base class (part of the supplied Class Library) and inherited by all classes. When you finalize an object, the method returns a null object handle.

A null object handle is always taken to refer to the NilObject. Should you accidentally send a message to the NilObject it will raise a "doesNotUnderstand" exception.

You may have copies of the object handle to a finalized object in data items other than the one you used in the "finalize" message. Sending a message to an object handle after the object to which it refers has been finalized gives unpredictable results:

Some Class Library objects contain references to other objects (for example, collection objects). When you send the containing object "finalize", the objects it contains do not get finalized. If the only references you had to these objects were the ones held in the containing object, you can now no longer reach or destroy those objects.

Class library container objects, such as the collection objects, respond to the "deepFinalize" message. This destroys all the objects within the container as well as the container itself. You may want to consider implementing "deepFinalize" in any objects of your own which contain other objects, or reimplementing "finalize" to destroy contained objects.

Which is appropriate depends on the nature of the containing object. If the containing object is the sole owner of the objects, it should implement its own version of "finalize". If the containing object is storing objects as an access mechanism for other clients, it should only destroy them if it receives a "deepFinalize".

19.6.1.1 Object Destruction Guidelines

This topic provides some guidelines on destroying objects:

However, if you have passed an object to another part of your application, you may not know whether the object is still in use or not. You should establish rules which state whether or not an object passed to another object can be destroyed.

The supplied Class Library uses these rules:


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousRequirements-based Vocabulary Tutorial (UNIX) Class ProgramsNext"