Objects and Messages Tutorial (UNIX) | Inheritance Tutorial (UNIX) |
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 program is built up, using relatively little syntax which is different from ANSI 85 COBOL. It is followed by sections in which you animate through the Stopwatch code.
This tutorial consists of the following sessions:
Time to complete: 45 minutes.
This tutorial starts with a look at the overall structure of a class program, using the Editor to examine the structure of Stopwatch.
The class program consists of a set of nested programs. Nesting programs is a concept which was introduced to COBOL in the ANSI 85 standard.
The sections below examine the following elements of the class program:
To load Stopwatch into the Editor:
editor stopwtch.cbl
As you read the explanations in the following sections, use the editor to locate and examine the code in stopwtch.cbl.
Each class program 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 data is protected inherits from Base. ... end class Stopwatch.
The inherits from
phrase identifies Stopwatch's
superclass, Base. The data is protected
phrase
enables any subclasses of Stopwatch to inherit Stopwatch data. If
this clause is omitted, or replaced by data is private
,
subclasses of Stopwatch cannot access inherited data directly. Inheritance
of data is explained in more detail in the Inheritance Tutorial.
To see this code:
The class-control
paragraph
identifies the executable code files which implement classes used
by the program. The superclass, the class itself, and every class
which will be invoked from the class must be identified in class-control
.
To see the class-control
paragraph for Stopwatch
class-control
paragraph, located directly below tag S005.
Scroll down the text edit pane until you get to the class-control
paragraph, located below tag S005.
The class-control
paragraph looks like this:
class-control. Base is class "base" StopWatch is class "stopwtch" .
The is class
clause serves two purposes:
On Object COBOL on UNIX, a class is guaranteed to be loaded before the class object receives its first message. Usually this occurs when you send the first message to the class object, but before the class object receives it.This is the same behavior as Object COBOL on other 32-bit platforms.
The class object program defines the data and methods for the class object. It is nested within the class program, immediately following the class program data division (if there is one). It looks like this:
class-object. object-storage section. * class data . ... * class methods end class-object.
The Object-Storage Section defines the class object data. The class object data can only be accessed from the class methods. It can also be inherited for direct access by subclasses (this depends on the contents of the Class-Id paragraph).
Each class method is a nested program. The code below shows an outline for a "new" method for Stopwatch.
method-id. "new". ... linkage section. 01 lnkStopwatch object reference. procedure division returning lnkStopwatch. * code to create and initialize a Stopwatch object. exit method. end method "new".
As with the class program 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:
Variables used by the method for processing. Data in working-storage is never reinitialized between different invocations of the method. This Working-Storage data is also shared between all instances of the object - you can't rely on it not being overwritten by a different instance between invocations.
Variables needed to support recursive working by the method. When a method is called recursively, new local-storage data is created for each level of recursion. You have to initialize the data items within the method code; although VALUE clauses in Local-Storage are accepted by the Compiler, they have no effect at run-time.
Variables passed as parameters to and from the program.
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
This method uses a Linkage Section to return data from the method.
The object program defines the data and methods for instances of the class. It is nested within the class program. It looks like this:
object. object-storage section. * instance data for the object. ... * Instance methods end object.
The only Data Division section that has any meaning in an object program is the Object-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 Object-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 program, 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 program and data declarations paragraph for Stopwatch
The OBJECT header and Object-Storage Sections are located below tags B009 and B010.
Instance methods are nested inside the object program. Writing an instance method is exactly like writing a class 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
This method does not declare any data of its own, but makes changes to the object's state by altering data declared in the Object-Storage Section.
The code below summarizes the structure of an Object COBOL class, and recaps the material covered so far in this tutorial.
class-id. Stopwatch inherits from Window. *> Identification and inheritance class-control. *> Class control paragraph *> names the files Stopwatch is class "stopwtch" *> containing the Window is class "window" *> executables for each *> class. . *> Period terminates paragraph. data division. *> Data division header is *> optional. ... working-storage section. ...
procedure division. *> procedure division is *> optional. You can *> use it for class *> initialization. exit program. *> Terminates procedure division *> division. class-object *> Defines the start of the class *> object. object-storage section. *> Defines class object data ... ... method-id. "new". *> Start of class method "new". ... end method "new". *> End of class method "new". end class-object. *> End of the class object object. *> Start of the code *> defining behavior *> of instances *> of the class. object-storage section. *> Defines instance data. ... method-id. "start". *> Start of instance *> method "sayHello" ... end method "stop". *> End of instance method. end object. *> End of code for *> instances. end class Stopwatch.
This completes the summary of class structure. In the next section you will animate some of the Stopwatch code.
In this session, you will animate 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 Stopwatch is compiled for animation so that you can see the code execute.
To animate the Stopwatch class:
This compiles timer.cbl and stopwtch.cbl for animation.
anim timer
Animator starts with the statement below tag T001 highlighted ready for execution.
invoke StopWatch "new"
...
).
This sends the "new" message to the Stopwatch class, and execution switches to the "new" method of the Stopwatch class.
invoke super
"new"...
).
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 reimplement it usually do so to send an initialization message to the new object. In this case we have overriden it to keep track of the number of instances created.
add 1 to osCount
).
Data item osCount is part of the class data, which is declared in the class Object-Storage Section.
exit method
statement to return
from the method back to timer.cbl.
invoke wsStopWatch1
"start"
).
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 Object-Storage Section below the Object header. They can't access data declared in the class object (between the Class Object and End Class-Object headers).
The "start" method tests to see whether the stopwatch is currently running, and if it isn't, stores the current time in Object-Storage, in the startTime variable.
if watchStopped
),
up to and including the exit method
statement.
Control returns to timer.cbl.
invoke
StopWatch "new" ...
): push the Perform Step keys.
This creates a second stopwatch; using perform step saves you from having to step through all the "new" code a second time.
invoke Stopwatch
"howMany"
).
Execution switches to the "howMany" method of Stopwatch. This is a class method (between the Class-object and End Class-Object headers), and returns the value in class data variable osCount.
move osCount to
lnkCount
) up to and including exit method
.
invoke wsStopwatch2
"start"
).
Execution switches to the "start" method of Stopwatch.
When you executed this method previously, on step 8, 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.
exit
method
statement.
Control returns to timer.cbl. At this point you have seen class object and instance object code executing, and how different instances have different data.
You can animate the rest of the code if you are interested to see how the Stopwatch works.
This concludes this tutorial on writing a class program. In this tutorial you learned:
The next tutorial explains inheritance in more detail.
Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.
Objects and Messages Tutorial (UNIX) | Inheritance Tutorial (UNIX) |