Chapter 9: Simple Class Tutorial

In the Objects and Messages Tutorial you learned how to create instances of a class and send messages. In this chapter you will learn how to write classes for objects of your own, using the example Stopwatch class introduced in the Objects and Messages Tutorial.

The first part of the discussion looks at the way a class is built up. It is followed by sections in which you debug the Stopwatch code.

This tutorial consists of the following sessions:

  1. Structure of a class
  2. Debugging the stopwatch

Structure of a Class

This tutorial starts with a look at the overall structure of a class source element, using the Editor to examine the structure of Stopwatch.

The class source element consists of a set of nested source elements.

The sections below examine the following elements of the class source element:

To load Stopwatch into the Editor:

  1. Start the Net Express development environment.
  2. Click File > Open, and open Examples\Net Express IDE\Stopwatch\Stopwatch.app. You'll see the .cbl files in the project window.
  3. Double-click stopwtch.cbl.

    The Editor opens with stopwtch.cbl displayed. As you read the explanations in the following sections, use the Editor to locate and examine the code in stopwtch.cbl.

Identifying a Class

Each class source element starts with a class-id identifier and finishes with an End Class clause. These bracket the outermost level of the nesting. The Stopwatch class looks like this:

class-id. Stopwatch as "stopwtch"
                inherits from Base.
  ... 
 end class Stopwatch.

The Inherits From phrase identifies Stopwatch's superclass, Base.

To see this code:

Identifying Classes Used by a Program

The Repository paragraph identifies the executable code files which implement classes used by the program. The superclass and every class which will be invoked from the class must be identified in the Repository paragraph.

To see the Repository paragraph for Stopwatch, scroll down the text edit pane until you get to the Repository paragraph, located below tag S005.

The Repository paragraph looks like this:

repository.
          class Base as "base".

The Class clause serves two purposes:

The Factory Object Source Element

The factory object source element defines the data and methods for the factory object. It is nested within the class source element, immediately following the class source element's Data Division (if there is one). It looks like this:

   factory.
   working-storage section. 
  * factory data .  
   ...
  * factory methods
   end factory.

The factory object data is defined in the Working-Storage Section. The factory object data can only be accessed from the factory methods

Factory Methods

Each factory method is a nested source element. The code below shows an outline for a "new" method for Stopwatch.

 method-id. "new". 
 ... 
 linkage section. 
 01 lnkWatch            object reference.
 
 procedure division  returning lnkWatch.
* code to create and initialize a Stopwatch object.
 exit method.
 end method "new".

As with the class source element itself, you can declare different types of data in the Data Division of the method. The Data Division header itself is optional. Data declared here is only accessible to the code in this method. The Data Division can contain any of the following sections:

The Procedure Division contains the code for the method. You terminate processing of the method with an Exit Method statement. This returns processing to the program which invoked the method.

To see the "new" method, use the Editor to locate the "new" method, below tag S015. This method uses a Linkage Section to return data from the method.

The Instance Object Source Element

The instance object source element defines the data and methods for instances of the class. It is nested within the class source element. It looks like this:

   object.
   working-storage section. 
  * instance data for the object.  
   ...
  * Instance methods
   end object.

The only Data Division section that has any meaning in an object source element is the Working-Storage Section. You can create other data sections, but the run-time behavior if you try to access the data in these sections is undefined.

Any data you declare in the Working-Storage Section is accessible to all the instance methods, and may be inherited by instances of subclasses of the class.

There is no Procedure Division in an object source element, only methods. To write an initialization method for instances, write a method called "initialize", and then invoke it from the "new" method for the class after you have created an instance.

To see the object source element and data declarations paragraph for Stopwatch, use the Editor to locate the OBJECT header. The OBJECT header and Working-Storage Sections are located below tags S030 and S035.

Instance Methods

Instance methods are nested inside the object source element. Writing an instance method is exactly like writing a factory method, with the only difference being the scope of data which the instance method can access.

The instance method can access data:

To see the "start" method for Stopwatch, use the Editor to locate the "start" method, just below tag S040. This method does not declare any data of its own, but makes changes to the object's state by altering data declared in the Working-Storage Section.

The code below summarizes the structure of a COBOL class, and recaps the material covered so far in this tutorial.

 class-id. Stopwatch as "stopwtch"
                 inherits from Base.
                              *> Identification
                              *> and inheritance

 repository.                  *> Repository paragraph names
                              *> the files containing the
 class Base as "base"         *> executables for each
                              *> class.
 .                            *> Period terminates paragraph.
 ...
     factory.                 *> Defines the start of the 
     working-storage section. *> Defines factory object data
     ...
         method-id. "new".    *> Start factory method "new". 
         ...
         end method "new".    *> End factory method "new".
    end factory.              *> End factory object

    object.                   *> Start the code defining
                              *> behavior of instances
                              *> of the class. 
    working-storage section.  *> Defines instance data. 
     ...
         method-id. "start".  *> Start instance 
                              *> method "sayHello"
         ...
         end method "stop".   *> End instance method. 
    end object.               *> End code for 
                              *> instances.  

 end class Stopwatch. 

This completes the summary of class structure. In the next section you will debug some of the Stopwatch code.

Debugging the Stopwatch

In this session, you will debug some of the code in the Stopwatch class, to see how classes and objects work. You are going to use the same programs as in the Objects and Messages Tutorial, but this time you will step through the code in Stopwatch so that you can see the code execute.

To debug the Stopwatch class:

  1. Start the Net Express development environment.
  2. Click File > Open, and open Examples\Net Express IDE\Stopwatch\Stopwatch.app. You'll see the .cbl files in the project window.
  3. Click Build > Rebuild All.

    This compiles timer.cbl and stopwtch.cbl.

  4. Click Debug > Start Debugging Click OK.

    The Debugger starts with the statement below tag T010 highlighted ready for execution.

  5. Step this statement.

    This sends the "new" message to the Stopwatch class, and execution switches to the "new" method of the Stopwatch class.

  6. Step the statement below tag S015.

    The mechanism for actually creating a new object (allocating the memory and returning an object handle) is inherited from the supplied class library, and this statement executes the inherited method. Some classes do not implement the "new" method at all, but rely on the inherited method. Those that re-implement it usually do so to send an initialization message to the new object. In this case we have overridden it to keep track of the number of instances created.

  7. Step the statement below tag S020.

    Data item osCount is part of the factory data, which is declared in the factory Working-Storage Section.

  8. Step the the Exit Method statement to return from the method back to timer.cbl.
  9. Step the statement below tag T020.

    Control switches to the "start" method of Stopwatch. Scroll up through the code to the OBJECT header (between tags S030 and S035). Methods which appear after the OBJECT header are instance methods, and can access data declared in the Working-Storage Section below the OBJECT header. They cannot access data declared in the factory object (between the FACTORY header and END FACTORY marker).

    The "start" method tests to see whether the stopwatch is currently running, and if it isn't, stores the current time in working storage, in the startTime variable.

  10. Step through the code below tag S045, up to and including the Exit Method statement.

    Control returns to timer.cbl.

  11. Click (This is equivalent to clicking Debug > Run Thru.

    This creates a second stopwatch without you having to step through all the "new" code a second time.

  12. Step the statement below tag T040.

    Execution switches to the "howMany" method of Stopwatch. This is a factory method (between the FACTORY header and END-FACTORY marker), and returns the value in factory data variable osCount.

  13. Step the statements below S025 up to and including the Exit Method statement.
  14. Step the statement below tag T050.

    Execution switches to the "start" method of Stopwatch.

  15. Double-click the data item watchrunning. The Examine List window opens, displaying the data item.

    When you executed this method previously, on step 9, you set watchRunning to true, but now it reads false. The reason is that each different instance of Stopwatch has its own unique data. The last time you executed this method, you sent the "start" message to the instance of Stopwatch represented by the handle in wsStopwatch1; this time you have sent it to a different instance, which has its own data.

  16. Step through the code up to and including the the Exit Method statement.

    Control returns to timer.cbl. At this point you have seen factory object and instance object code executing, and how different instances have different data.

    You can debug the rest of the code if you are interested to see how the Stopwatch works.

  17. When you have finished, click Debug > Stop Debugging to stop the Debugger.

Summary

This concludes this tutorial on writing a class. In this tutorial you learned:

The next tutorial demonstrates some more features of OO COBOL.


Copyright © 2009 Micro Focus (IP) Ltd. All rights reserved.