Chapter 5: Methods

This chapter explains how to write methods, with short examples of code. For full syntax definitions, see your Language Reference.

Overview

You write methods inside class source elements, which are described in the chapter Classes. Each method is a nested source element bracketed by METHOD-ID and END METHOD headers. You may optionally precede the first METHOD-ID header by an IDENTIFICATION DIVISION header. Factory methods appear inside the factory object source element. Instance methods appear inside the instance object source element, following the Working-Storage Section.

If the object that you are coding implements an interface, you must write methods for every method prototype in the interface. For further information about interfaces and method prototypes, see the chapter Interfaces.

Method Data

Factory methods can access factory Working-Storage data and instance methods can access instance Working-Storage data. In all other respects factory and instance methods look and work identically.

A method can also have data of its own; you can declare the following types of storage section in a method:

The following piece of code shows an example method, "setInItemA" which stores a single character and converts it to upper case. The method returns 1 if the character was already in upper case and zero otherwise. It refers to a data item, clItemA, which you can assume is declared in the Working-Storage Section of the instance object.

 method-id. setInItemA. 
 local-storage section.
 
 01  aTempItem        pic x(4) comp-5.

 linkage section. 

 01  lnkValue         pic x.
 01  aResult          pic x comp-5.

 procedure division using lnkValue
                returning aResult.
     move lnkValue to inItemA
     move 1 to aTempItem
     call "CBL_TOUPPER" using inItemA
                     by value aTempItem
     if lnkValue = clItemA
        move 1 to aResult
     else 
        move 0 to aResult
     exit method. 
  end method setInItemA.

The method uses local storage for all its temporary working data. The run-time system allocates memory for local storage each time the method is invoked, and deallocates it after executing the EXIT METHOD statement. This has the advantage of supporting recursion. A method may be recursive even if it doesn't invoke itself directly; it may invoke a method in a different object which invokes the original method a second time.

The Linkage Section is used to declare all parameters passed to or from the method. Usually parameters are passed by reference, which means that no actual memory is allocated for Linkage Section items.

Predefined Object Reference Names

Quite often a factory or instance object may need to send a message to itself. The three most common reasons are listed below:

Three predefined object reference names, which are initialized by the run-time system when an object is created, are available to class source elements to enable them to send messages to themselves. They are:

Note: You can also use SELF and SELFCLASS as object reference data items that you can pass as parameters to other methods.

One further predefined object reference name is available; this is NULL. NULL contains the null object refernce value, that is, a value that is guaranteed not to point to an object.

Micro Focus extensionThe predefined object reference NIL is also available. NIL and NULL have the same meaning.

The OO COBOL system also uses one external variable, OO-DESKTOP. This is used with the GUI classes in the supplied class library.

You must not change the contents of any of the predefined object references or of OO-desktop.

SELF, SUPER, SELFCLASS, NULL and NIL are all reserved words.

Instance Creation Methods

You need to be able to create instance objects from your classes. At its simplest, creating a new object instance means getting a memory allocation for its data and an object handle by which you can refer to it. This basic task is handled by an instance method in the metaclass Behavior, called "new". All factory objects are instances of the metaclass, and so inherit this method

If you do not want to carry out any initialization for an instance, you do not need to code anything in the class for its creation; you can simply inherit the "new" method from the metaclass. The example class below works like this:

 class-id. simple inherits from base.
* No factory methods for simple 
 ...
 object.
 working-storage section.
     01   simpleInstanceData            pic x(80).  
* Instance methods for simple are not shown here.  
 ...
 end object.
 end class simple. 

When your application wanted a new instance of Simple, you would code:

 invoke simple "new" returning anObject

where anObject is a data item of type object reference. The "new" method allocates the 80 bytes required for an instance of simple and puts an object handle into anObject.

In many cases you will want to carry out some instance initialization on objects created, in which case you have to code your own factory method for creating instances. However, your own instance creation methods will always use Behavior method "new" as the basic mechanism for creating an object and allocating memory. For example:

 class-id. A inherits from Base.
 ...
 factory.

 ...

 method-id. newWithData. 
 linkage section. 
     01 lnkObject      object reference A.
     01 lnkName        pic x(80). 

 procedure division using lnkName 
                returning lnkObject. 
     
*----Create a new instance of A using the "new" method 
*----from Base
     invoke super "new" returning lnkObject 
*----Send it an initialize message. 
     invoke lnkObject "initialize" using lnkName
     exit method. 
 end method newWithData. 
 end factory. 
 object.
 working-storage section.    
     01  theName     pic x(80).   
 
    ...

 method-id. initialize.
 
 linkage section. 
    01  lnkName     pic x(80).
 procedure division using lnkName.
*----Store the initialization parameter in the object's 
*    instance data
     move lnkName to theName
     exit method.  
 end method initialize. 

 ...

 end object.
 end class A. 

The "newWithData" method in class A sends the "new" message to SUPER, introduced in the section Predefined Object Reference Names. Sending a message to SUPER is very similar to sending it to SELF; the only difference is that the run-time system starts looking for a matching method in the code of your superclass rather than in the code of this class.

There is no rule that says that you have to name an instance creation method "new", although it is used by convention as it makes it obvious what the method does.

Get and Set Property Methods

A frequent coding requirement is the setting of a number of data fields to particular values; for example, a program reads in details of a new customer, and needs to create a new record in a file or a new row in a database table containing the information about the customer. To meet this requirement in an OO application, you need a method for each field that sets the required value. Methods that set values are known as set methods.

Another frequent coding requirement is the retrieval of information from a number of data fields; for example, a program that displays information about existing customers needs to obtain the information from records in a file or rows in a database table containing the information about the customers. To meet this requirement in an OO application, you need a method for each field, that gets the required value. Methods that get values are known as get methods.

Coding get and set methods for a number of data fields can be quite tedious, so OO COBOL provides two mechanisms that reduce the amount of programmer effort:

Both of these mechanisms work with object properties. Object properties provide syntax to get information out of and pass information back into objects.

PROPERTY Clause in a Data Item Definition

If you code the PROPERTY clause in a data item definition, the Compiler automatically generates simple get property and set property methods for you. These methods differ slightly depending on the data description. For details of the methods generated see your Language Reference.

For example, in your class program you might code:

 class-id. A inherits from Base.
...
factory.
...
end factory.
object.
      working-storage section.  
      01  custNo  pic 9(10)  comp property.       
      ...
end-object.
end class A.

The Compiler generates get property and set property methods for cust-no, with internal method names. You do not need to know what these method names are, because you do not call them directly. To find out how to use the methods, see the section Coding the Object Property Syntax.

PROPERTY Clause in a Method Definition

With this mechanism, you write get and set methods, but use the PROPERTY clause in the Method-ID paragraph of each method, so that the Compiler can generate internal method names which will work with the object property syntax. Use this mechanism if you need methods that do more than the simple methods generated when you specify the PROPERTY clause in a data definition.

For example, your class source element might include the following code:

class-id A inherits from Base.
...
object.
working-storage section.
01 custNo pic 9(10).
method-id. get property custNo.
linkage section.
01 lkCustNo pic 9(10).
procedure division returning lkCustNo.
   *> My other code here
    move custNo to lkCustNo
    *> My other code here
    exit method.
end method.

method-id. set property custNo.
linkage section.
1 lkCustNo pic 9(10).
procedure division using lkCustNo.
   *> My other code here
    move lkCust-no to custNo
    *> My other code here
    exit method.
end method.

The Compiler generates internal method names for the get and set methods for the custNo data item.

Coding the Object Property Syntax

You use the get and set property methods by coding the object property syntax in your Procedure Division. In the following example a procedural program sets the custNo object property:

 program-id. PROG1.
 repository.  
    class A. 
    property custNo.
 working-storage section.
 01 cust-no-in PIC 9(10) comp.
 01 obj-ref usage object reference class A.
 procedure division.
   ...
* invoke SET PROPERTY method
    move cust-no-in to custNo of obj-ref 

In the following example a procedural program gets the custNo object property:

 program-id. PROG1.
 repository.
     class A.
     property cust-no.
 working-storage section.
 01 cust-no-out PIC 9(10) comp.
 01 obj-ref usage object reference class A.
 procedure division.
   ...
* invoke GET PROPERTY method
    move custNo of obj-ref to cust-no-out 


Copyright © 2004 Micro Focus International Limited. All rights reserved.