This chapter describes the Micro Focus syntax and mechanisms that provide alternatives and extensions to the ISO 2000 syntax
The following table shows an outline of a class coded using the ISO 2002 OO COBOL syntax in the left-hand column and the same class coded using the Micro Focus alternative syntax in the right-hand column. Your COBOL system supports all the syntax in both columns. Not all the syntax available is shown; for full details of all the OO COBOL syntax see your Language Reference.
|ISO 2002 OO COBOL Syntax||Micro Focus OO COBOL Syntax|
class-id. Example inherits from Base. environment division. ... configuration section. repository. class Example as "exmp" class Base as "base" class CharacterArray. ... factory. data division. working-storage section. ... method-id. "newWithData". ... end method "newWithData". end-factory. object. working-storage section. ... method-id. "sayHello". ... end method "sayHello". end object. end class Example.
class-id. Example inherits from Base. environment division. ... object section. class-control. Example is class "exmp" Base is class "base" CharacterArray is class "chararry". data division. ... class-object data division. object-storage section. ... method-id. "newWithData". ... end method "newWithData". end class-object. object. object-storage section. ... method-id. "sayHello". ... end method "sayHello". end object. end class Example.
In Micro Focus OO COBOL you can code a Data Division in the class source element. This Data Division can contain a Working-Storage Section only. Data defined in this Working-Storage Section is known as shared data, because it is accessible from class methods (factory methods) and instance methods.
In Micro Focus COBOL you can use working storage for temporary variables inside a method, but this remains permanently allocated, and is shared by all invocations of the method, in all objects of the same class. This means that it is not suitable for any method that could be invoked recursively or in a multi-threaded environment. For example, method "setData" in object A1 (an instance of class A) invokes method "getDetails" in object B1. The method in object B1 does a "setData" in object A2 (also an instance of class A). Any data in working storage from the original invocation of "setData" (which has not yet finished execution) is overwritten by the second invocation. Local storage data for the two invocations of "setData" would be kept completely separate.
In Micro Focus OO COBOL you store class object data in the Object-Storage Section of the class object source element, and instance object data in the Object-Storage Section of the object source element. In ISO 2002 OO COBOL, you store this data in the Working-Storage Sections of the factory and object source elements. A setting of the OOCTRL run-time flag controls how the Compiler treats Working-Storage Sections.
Data inheritance in Micro Focus OO COBOL has a richer meaning than the same term in ISO 2002 OO COBOL. In ISO 2002 OO COBOL, data inheritance is the ability of a factory object to access data declared in the factory object of an inherited class through the factory methods of that class, and also the ability of an instance object to access data declared in the instance object of an inherited class through the instance methods of that class. Micro Focus OO COBOL supplies this same ability. In addition, in Micro Focus OO COBOL you can use syntax that enables your subclasses to access data declared in inherited classes directly. This is called direct data inheritance.
A class can optionally directly inherit the data declared in the Object-Storage Sections of its superclass. The next two sections explain:
Inheritance of data is controlled by two optional clauses in the CLASS-ID header at the beginning of the class.
The first of these, DATA IS PROTECTED, enables subclasses to access the class's own data directly. (There is a synonym for this phrase, DATA IS RESTRICTED). The second of these, WITH DATA, enables a class to access its superclass's data directly. For example:
class-id. B data is protected inherits from A with data.
This says that B inherits all the data in A, and that any subclass of B can also inherit B's data (which would include A's data).
When you compile class B, the WITH DATA clause causes the Checker to look for two files: a.cls and a.ins.
You cannot use multiple inheritance (allowed in ISO 2002 syntax) and the Micro Focus WITH DATA clause in the same Class-ID paragraph. For example, the following code is illegal:
class-id. C inherits from A, B with data.
The .cls file is a COBOL copyfile containing the data definitions for the class object data and the .ins file is a copyfile containing the data definitions for the instance data. The Checker inserts these automatically at the start of the Object-Storage Sections for class and instance data when it compiles the source code for class B.
The DATA IS PROTECTED clause causes the COBOL Checker to generate two files: b.cls and b.ins. These copyfiles start with all the definitions for inherited data, which is followed by the definitions for any class or instance data declared in class B.
The use of copyfiles to implement data inheritance has the following implications:
You might want to prevent subclasses from inheriting data, in which case you can either omit the DATA IS PROTECTED clause or replace it by DATA IS PRIVATE. This stops the Checker from creating the .cls and .ins copyfiles. The following Class-ID header would mean that B still inherited A's data, but that subclasses of B would not be able to inherit B's data:
class-id. B data is private inherits from A with data.
You might code another class that starts like this:
class-id. C data is protected inherits from B with data.
When you try to compile the class for C, the Compiler will stop with the following message:
FILE below not found - Stop/Retry/Continue/Alter-path: B.CLS
Unless you can give the Compiler a path where it can find a copy of b.cls, you will have to stop the compilation, and alter the source code for C so that it no longer tries to inherit data from B.
Note: If you change a class from having protected data to private data, the Compiler does not delete its .cls and .ins files if they already exist.
When you inherit data from a superclass, the Compiler puts a copy of all the class object data definitions from the superclass in your class Object-Storage Section, and a copy of all the instance object data definitions in your instance Object-Storage Section.
The diagram in Figure 12-1 shows three classes, A, B and C. C inherits from B without data, and B inherits from A with data. Class A implements instance method "setInDataA" which sets a value into data item instanceItemA. On the right-hand side of the dotted line are three instance objects, A1, B1 and C1, created at run time by class objects A, B and C.
If object B1 gets the message "setInDataA", the message gets executed by the instance method implemented in A (because B does not implement this method). However, the data item that gets updated is instanceItemA held in instance object B1's storage.
Because class B inherits from A with data, the source code in class B can also manipulate instanceItemA directly. For example, the programmer for class B could code an instance method containing the statement:
move "!" to instanceItemA
Object C1 also has memory allocated for instanceItemA and instanceItemB in its Object-Storage Section at run time. However, because it does not inherit with data, the Checker does not know the definitions of these items when Class C is compiled. The value for instanceItemA can only be set by sending class object C the "setInDataA" message.
move "!" to instanceItemA
in an instance method of C would be rejected by the Checker at compile-time. The programmer of Class C can set instanceItemA by coding inside an instance method:
invoke self "setInDataA" using "!"
This sends the "setInData" message to instance object C1 at run time, and it gets passed up the inheritance chain until it reaches class A. The object reference SELF is a reserved name which always refers to the object in which it occurs (see the section Predefined Object Reference Names in the chapter Methods).
Figure 12-1: Data Inheritance
Extending a class enables you to add new methods to an OO COBOL class without changing the original source code. Class extension is a Micro Focus OO COBOL extension.
The difference between extending a class and subclassing it is that the extensions are inherited by all existing subclasses.
For example, if class A has a subclass, class B, you can add functionality to class A by subclassing it to create subclass C. However, class B will not inherit the functionality of class C, because it is a subclass of A. If you extend class A with a class extension, X, the effect at run time is the same as if you had changed and recompiled class A. Class B inherits all the extra functionality in class X.
To extend a class, write a class program where the class header looks like this:
class-id. ExtensionName extend OriginalClass [with data].
The Class-Control paragraph must contain references to the extension class and the class which it extends. Use the WITH DATA clause to enable the extension class to reference class and instance data of the original class directly. The extension class cannot declare new class or instance data of its own, although it can declare its own working storage.
To use the class extension, you must insert a COBOL CALL to it at any point in application execution before the class extensions are used, to register the new methods with the run-time system.
The three short classes below show how class extension works. Class A is a subclass of Base and class B is a subclass of A. Neither of these classes have any methods. Class Axtnd is a class extension for A.
class-id. a inherits from base. class-control. a is class "a" base is class "base" . class-object. end class-object. object. end object. end class a.
class-id. b inherits from a. class-control. b is class "b" a is class "a" . class-object. end class-object. object. end object. end class b.
Class Axtnd (the extension of class A) implements a single instance method:
class-id. axtnd extend a. class-control. axtnd is class "axtnd" a is class "a" . object. method-id. "extendMethod". procedure division. display "I'm an extension" exit method. end method "extendMethod". end object. end class axtnd.
The next piece of code is a short test which shows how the extension works:
program-id. ExtensionTest. class-control. a is class "a" b is class "b" . working-storage section. 01 thisB object reference. procedure division. call "axtnd" *> Load class extension invoke b "new" returning thisB *> Create instance of B invoke thisB "extendmethod" *> Send a message stop run.
When you run the ExtensionTest program, it loads class Axtnd. All methods implemented in this class are now accessible as though they were methods of class A. When the test program sends the "extendMethod" message to an instance of class B, the extension method is executed, as though it were implemented in class A and inherited by class B.
Copyright © 2003 Micro Focus International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.