MICRO FOCUS - Object Oriented Programming With Cobol
MICRO FOCUS - Object Oriented Programming With Cobol
2EMHFWRULHQWHG
Issue 2b, March 2004
&2%2/
REMHFWRULHQWHG
SURJUDPPLQJZLWKFRERO
20040316122346
Table of Contents
About this Book. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Command Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Side Headings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
12
13
Part 1: Overview
1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Object-oriented COBOL syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
Developing OO Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
19
19
OO Programming Concepts . . . . . . . . . . . . . . . . . . . 21
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
35
35
36
37
Sending Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using the INVOKE Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Inline Method Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Invocation Using Object Properties . . . . . . . . . . . . . . . . . . . . . . .
38
39
39
40
Conformance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Creating a New Instance Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Destroying Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Object Destruction Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Finalized Object References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Class Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Method Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Data Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Files in OO Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Programming Factory Object Behavior . . . . . . . . . . . . . . . . . . . . . . .
Factory Object Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Class Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Factory Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
56
57
57
58
58
59
60
Parameterized Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
Method Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
67
69
71
72
72
73
......
......
......
......
........
........
........
........
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
75
Interface Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
Parameterized Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
81
81
83
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Preventing Reallocation of Object Handles . . . . . . . . . . . . . . . .
Finding Memory Leaks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Object Data Guard Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
84
85
86
Message Tracing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
Troubleshooting Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Memory Exceptions and Protection Violations on Method
Invocations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Symbol Redefined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Program Not Found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
89
90
90
Part 3: Tutorials
8
101
102
102
103
103
104
105
138
138
139
141
152
153
154
156
156
157
.......
.......
.......
.......
.
.
.
.
182
183
185
185
10
Part 7: Appendices
A Descriptions of OO Run-time Switches . . . . . . . . . . 229
List of Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
11
Audience
You should be familiar with the COBOL language and with your
operating system. You should read the Getting Started book and be
familiar with the COBOL development cycle described in your
documentation.
Notation
The notation used in the books is as follows:
With COMP-X and COMP-5, PIC X is used rather than PIC 99. Unlike
PIC 99, PIC X shows the length of the data item directly and so
demonstrates more clearly the use of COMP-X, which is to define a
binary item of the specified number of bytes.
12
Command Lines
The notation used to describe the format of command lines is as
follows:
Words printed in nonitalic characters are the actual words you must
enter.
Windows:
UNIX:
Braces { } mean you must choose from the options inside them. If
there is only one option in the braces, they mean repetition.
If a command line does not fit across the page, it is continued on the
next line; the continuation line is indented.
Server Express:
On UNIX, all command line formats and examples are for the
standard UNIX shell, the Bourne shell. If you are using another shell,
see your UNIX documentation for the appropriate formats.
Server Express:
Server Express:
Some keystrokes using function keys or the Alt or Ctrl keys are not
available on all UNIX platforms. The Users Guide contains a UNIX
Key Usage Chart, listing how the keystrokes shown in the books
map onto actual keystrokes.
Notation
Side Headings
In a generic book or chapter, text that does not apply to all supported
environments and COBOL systems is marked by a side heading in the
left margin. A side heading applies to the paragraph it is next to, unless
it is next to the first paragraph in a section, in which case it applies to
that whole section.
The following examples of side headings show what they mean:
Server Express:
Net Express:
13
14
15
Part 1: Overview
This part contains the following chapters:
Chapter 1, Introduction
16
Part 1: Overview
17
1 Introduction
This chapter introduces the facilities for object-oriented programming
provided in your COBOL system, and explains how to use this book to
begin OO programming with COBOL.
You can choose to just use ISO 2002 syntax, or you can use ISO 2002
and Micro Focus syntax, mixing them in the same program. However,
we recommend that you use the ISO 2002 syntax if you want your
programs to be portable to platforms that do not support Micro Focus
COBOL.
The chapters in Parts 1, 2 and 3 of this book use the ISO 2002 syntax
and related terminology. Micro Focus alternatives and extensions are
generally mentioned when a new piece of syntax is introduced.
The chapters in Parts 4, 5 and 6 of this book use the Micro Focus syntax
and related terminology. The main differences between ISO 2002 and
Micro Focus OO COBOL are listed in the chapter Micro Focus OO COBOL
Alternative Syntax, in Part 4.
18
Chapter 1 Introduction
Developing OO Programs
Development starts with the analysis of the problem and the design of a
program or programs that solve the problem. Object-oriented design
involves identifying the objects that you want to work with and what
they need to do. Object-oriented analysis and design lie outide the
scope of this book; for a reading list, see the section Object-Oriented
Analysis and Design.
When you reach the design phase, you can make use of the Micro Focus
class libraries, as long as you do not want to port your programs to
platforms that do not support Micro Focus COBOL. A class library is a
collection of ready-made objects that you can use in your programs. (For
definitions of the terms class and object see the chapter OO
Programming Concepts.) More information on the Micro Focus class
libraries is available in the chapter Introduction to the Class Libraries.
ISO 2002 COBOL also provides a class library. However, it includes far
fewer classes than the Micro Focus class libraries.
When you start coding your program you will be on familiar territory,
using your usual development environment tools such as the Editor and
Animator.
Net Express:
If you use both Net Express and Server Express, you can develop and
debug your application on Net Express, and transfer the code to a
Server Express platform for production. OO COBOL code is portable
between Net Express and Server Express, except for code developed for:
GUI programming
COM components
19
20
Chapter 1 Introduction
21
2 OO Programming Concepts
This chapter describes the key concepts supported by an objectoriented programming language, and how they are implemented by
Micro Focus COBOL. Micro Focus COBOL supports the ISO 2002
standard for Object-Oriented COBOL (OO COBOL) and supplies some
additional OO facilities.
Overview
OO COBOL provides the following elements, which are typical of any
OO programming language:
Objects
Classes
Methods
Interfaces
Messages
Encapsulation
Inheritance
Polymorphism
22
Objects
An object is a combination of data and the procedures to operate on
that data. The data is known as the objects attributes, and the
procedures are known as its methods. Every object in an object-oriented
application has a unique object identifier, allocated to it at creation and
fixed for its lifetime.
Objects hold data, but they do not replace files and databases. The data
in an object exists only during the lifetime of the object. Objects are
created and destroyed by object-oriented applications.
Many of the objects in an OO application represent objects in the real
world. For example, a banking system would include objects to
represent customers, accounts and ledgers. The attributes of an account
would include the balance, and its methods would include Debit, Credit,
GetBalance. Figure 2-1 shows two ways of representing such an object.
Figure 2-1. An Object
The user of an object can only find out about or change its attributes by
making requests to the object. These requests are known as messages,
and each message invokes a method supported by the object. The
object interface is a description of all the messages to which the object
responds. For example, to find out the balance of an account, you
would send an account object the message GetBalance.
The actual representation of the data is known only to the object. As
long as the object interface remains the same, a programmer can
Classes
Classes
A class is a definition of an object; it embodies all the information you
need to create and manipulate objects of a particular type. An account
class defines account objects and a ledger class defines ledger objects.
An account object is said to be an instance of the account class, or an
instance object, or simply an instance.
A class is a programming language construct, while an object is an
entity that exists in memory at run time.
A class not only defines an instance object; it also defines a factory
object. The factory object defines the classs own data and behavior.
The class does not have the same behavior as the instances it creates. A
class is like a printers plate, printing identical forms. A plate enables
you to print a form, but is not a form itself.
The main function of the factory object is to create new instance
objects, but it can also contain data and methods that are shared by all
instance objects. For example, the factory object of an account class
could include a data item for keeping a count of the number of account
objects created.
In OO COBOL, a class is a COBOL source element, which consists of a set
of nested source elements, including source elements for the factory
object and the instance object. The factory source element contains all
the attributes and methods specific to the factory object. The object
source element contains the attributes and methods specific to all
instance objects. Figure 2-2 shows a class and instances being created
from it.
23
24
The top-level source element for the class can contain data that is
common to all instance objects and the class object
Methods
Methods are the pieces of code that implement the behavior of an
object. In OO COBOL, each method is a separate source element nested
within the factory or object source element. An object method can
access its own data, the instance data and the factory data declared in
Interfaces
the factory object source element. A factory method can access its own
data and the factory data.
Methods can be incomplete; these are known as method prototypes. A
method prototype does not contain any code, just a heading and an
end-marker. A method prototype is always fully implemented
elsewhere in the application; for an explanation of the benefits of using
method prototypes see the section Interfaces.
Interfaces
Interfaces are collections of method prototypes. The set of method
prototypes defines a common behavior that a variety of objects might
share. For example, you might have an interface Rentable, that defines
methods appropriate for objects that people can rent, such as cars and
video tapes. The Car class is a subclass of the Vehicle class, while the
VideoTape class is a subclass of the VideoRecording class, but both Car
and VideoTape implement the Rentable interface. The interface
methods might include pickUp and dropOff. These are defined as
prototypes in the interface. Each class that implements the interface
must provide full method definitions for the method prototypes in the
interface.
Interfaces give you additional flexibility in designing your OO
applications; they are one of the elements in an OO language that
provide polymorphism (see the section Polymorphism).
Messages
A message is the way you request an object to perform a service. A
message always consists of the following:
Object reference
Method selector
25
26
Encapsulation
Encapsulation in OO langauges is the inclusion within an object of
everything it needs to function: its data and the implementation of its
methods. Other objects can use it as long as they adhere to the objects
interface; they do not need to know anything about the way the object
holds and manipulates its data. Encapsulation helps to preserve the
integrity of data.
Inheritance
Inheritance
Inheritance enables OO languages to mirror the real world more closely
by establishing hierarchies of classes. Most objects in the real world
belong to specific categories; for example, cars and motor bikes are
vehicles, managers and workers are employees. Using inheritance in OO
applications reduces coding effort, because you only need to include
methods in a subclass if the required behavior is different from that
provided in the superclass. When you create a method in a subclass of
the same name as a method in the class it inherits from, the method in
the subclass overrides the method in the class; the method in the
subclass is known as a reimplementation of the method in the class.
For example, our banking application might handle the following types
of account: checking accounts, credit card accounts and savings
accounts. There are some features that all these accounts have in
common; a balance attribute, methods credit, debit and getBalance. But
there are also differences; a savings account pays interest, while a
checking account may allow overdrafts.
An Account class implements all the methods and attributes common to
all its subclasses. The subclasses implement the attributes and methods
which they uniquely require.
A deposit account implements its own version of Debit that does not
allow overdrafts. Figure 2-4 shows a possible inheritance hierarchy for
bank accounts.
Figure 2-4. Bank Account Inheritance
27
28
Inheritance makes subsequent updates easier, because you can add new
subclasses as required. For example, the bank might introduce two new
types of savings account: an instant access account, and a high interest
account where you have to give notice of a withdrawal. These could be
subclassed from the Savings Account class, with additions to provide the
new behavior required. Because they still respond to the message
interface used by all account objects, the changes do not ripple through
the rest of the system.
Micro Focus COBOL comes with a number of class libraries. All the
classes in the Base Class Library are ultimately descended from class
Base. Base provides methods which are required by all classes, which
include methods for creating and destroying objects. The classes you
write are also likely to be subclasses of Base. You can create your own
root class and subclass from that, but you may need to duplicate some
of the services provided by Base.
In OO COBOL, a factory of a subclass has access to all the factory
methods of its superclasses. An instance of a subclass has access to all
the object methods of its superclasses.
OO COBOL provides multiple inheritance; this means that in addition to
a subclass inheriting all the methods of the classes above it in the
hierarchy, it can also inherit directly from more than one class. This is
illustrated in Figure 2-5.
Figure 2-5. Multiple Inheritance
Polymorphism
Polymorphism
Polymorphism is an important part of any object-oriented programming
language. Polymorphism means that the same message sent to different
objects can invoke different methods.
Polymorphism is provided by two mechanisms in OO COBOL:
Inheritance
Where a number of subclasses inherit from a class, the methods in
the class can be method prototypes, that is methods that dont
contain any code. Complete methods of the same name appear in
each subclass, and these can be different.
Interfaces
Interfaces are collections of methods applicable to a variety of
objects. Again, the methods in the interface are prototypes. If a
class implements an interface, it must provide complete methods of
the same name, and these methods can differ between classes that
implement the same interface.
29
30
31
Part 2: Object-oriented
COBOL Programming
This part contains the following chapters:
Chapter 4, Classes
Chapter 5, Methods
Chapter 6, Interfaces
32
33
Overview
Objects can be used by an application which is not itself objectoriented. The same rules apply whether the program you write is an
OO COBOL class, or a procedural COBOL program in which you want to
use COBOL objects.
Programs that use objects all have certain features in common:
34
Declaring Classes
If you want to use an object in a program, you must declare the objects
class in the programs Repository paragraph. This prompts the Compiler
to obtain information about the class from the external repository,
which is an area where information about classes and interfaces is held.
The availability of the external repository enables conformance
checking to take place (see the section Conformance). Information
about classes is added to the external repository when a class is
compiled.
The CLASS clause also:
Creates a data item for each class named. At run time, this data item
holds an object handle to the factory object.
Enables the run-time system to find and load the file with the class
executable code.
A class is guaranteed to be loaded before the factory object receives
its first message. Usually this occurs when you send the first message
to the factory object, but before the factory object receives it.
When you declare a class, it effectively makes the classs factory object
available. The class names in the Repository paragraph are
automatically declared as object reference data items. This enables you
to send messages to the factory object.
The code below shows class registration for classes CharacterArray and
Employee:
repository.
class CharacterArray as "chararry"
class Employee
If you code the AS clause, the Compiler uses the value of the literal as
the external name of the class program; otherwise it uses the class name
changed to upper case. If you are writing a class, you do not have to
include a CLASS clause for the class you are writing; if you do include
one, the Compiler ignores it and uses the class name or literal in the
Class-ID paragraph in the Identification Division.
Micro Focus COBOL provides alternative syntax; see the section
Summary of Syntax Alternatives in the chapter Micro Focus OO COBOL
Alternative Syntax.
anObject
usage object reference.
secdObject usage object reference factory of BankAccount.
thirdObject usage object reference active-class.
fourthObject usage object reference Rentable.
35
36
The second, third and fourth lines define typed object references:
The secondObject data item can hold a handle only to the factory
object of the class BankAccount or a subclass of that class.
The thirdObject data item can hold a handle only to an object of the
active class, that is, the class in which this data description appears
(either in the factory source element or the object source element),
or any subclass of that class. Object references of type active-class
cannot appear in procedural COBOL programs.
The fourthObject data item can hold a handle only to an object that
implements the Rentable interface. Interfaces are collections of
method prototypes that define behavior; for more information
about interfaces and how objects implement them see the chapter
Interfaces.
You do not need to declare object references for the factory objects of
the classes you are going to use in your program. These are declared
automatically when you list your classes in the Repository paragraph.
Test whether two object references refer to the same object. For
example:
if anObject1 = anObject2 ...
Micro Focus
Extension
Object Views
You can copy object references from one data item to another using the
SET statement, but only if the receiving object reference is to a subclass
of the class of the sending object reference. For example, if classes
circle, triangle and rectangle all inherit from class shape, the following
code is valid:
01 obj1 usage object
01 obj2 usage object
01 obj3 usage object
01 obj4 usage object
...
set obj1 to obj2
set obj1 to obj3
set obj1 to obj4
reference
reference
reference
reference
class
class
class
class
shape.
circle.
triangle.
rectangle.
37
38
A FACTORY clause, which asks the run-time system to check that the
object reference is pointing to the factory object of the class.
An ONLY phrase, which asks the run-time system to check that the
object reference is pointing to an object of that class only and not
any subclass.
Sending Messages
You send a message to an object to make it execute a method. The
method to be executed is named in 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 in the chapter Classes for more information).
There are three ways of sending a message:
Object properties
Sending Messages
39
40
This statement invokes the get property method balance of the account
object referred to by the object reference anAccount.
For more details see the section Get and Set Property Methods in the
chapter Methods.
Conformance
Conformance is a quality that applies to interfaces. The term interface is
used in two ways in OO COBOL:
Part of an objects interface (in the first sense) can be a set of methods
that it provides because it implements an interface (in the second
sense). Interfaces in the second sense are explained in more detail in the
chapter Interfaces.
It is essential in OO programming that, when your program is executed,
each object conforms to the interface that you defined for it. To help to
Conformance
If you want both checking and update, compile with the setting
REPOSITORY (UPDATE ON CHECKING ON).
You define classes B and C as inheriting from class A, and you set a
typed object reference for class B to a typed object reference for
class A; the Compiler rejects this, because at compile time the typed
object reference to class A might actually point to an object of class
C. (You can get round this restriction by using an object view, which
delays the checking until run time. For more information see the
section Object Views.)
41
42
Destroying Objects
Destroying Objects
Some OO programming languages perform garbage collection at run
time, that is, they automatically destroy objects that are no longer in
use. OO COBOL does not provide garbage collection. Once you create
an object, it remains in existence until destroyed explicitly, even if the
data item which holds its object handle is destroyed or goes out of
scope.
There are two ways an object can be destroyed:
43
44
If the object handle has not been reused by the run-time system, it
halts the application with a run-time error.
If the object handle has been reused by the run-time system, your
message is sent to the wrong object. If the object understands the
message, there will be no error informing you that something has
gone wrong.
Destroying Objects
45
46
47
4 Classes
This chapter explains the rules for writing classes, with short examples
of code. For full syntax definitions, see your Language Reference.
Overview
You need to write OO COBOL classes to create objects other than the
ones in the class libraries supplied by Micro Focus. When you write a
class, you need to understand three distinct entities:
The class
The source code defining the class.
Instance objects
Created by the factory object at run time.
A class embodies all the behavior for its factory object and its instance
objects. It defines the factory and instance data, and factory and
instance methods. A class also inherits the data and methods of its
superclass.
Methods are discussed both in this chapter, and in the chapter
Methods.
Net Express:
Net Express provides wizards that help you to create classes, methods
and data quickly. For more information see the Help topics To create a
class, To add a method to a class and To add a data item to a class.
48
Chapter 4 Classes
Class Structure
Each class describes the behavior of two different objects:
There is never more than one occurrence of each type of factory object
in an application, whereas there can be many occurrences of its
instances. The main function of any factory object is to create instances,
although in some cases a factory object has other behavior as well.
Micro Focus
Alternative
The code block below shows the outline of an example class. An ellipsis
(...) shows where code has been omitted, and indentation indicates the
levels of nesting.
Class Structure
Environment division
header is optional.
All sections legal in
MF or ANSI 85 COBOL
Environment Division
are valid, though not
shown here.
*>
*>
*>
*>
*>
*>
*>
*>
*>
*>
*>
Repository paragraph
names the classes this
class refers to.
Information for the
Example class is stored in
the external repository
under the name "exmp".
Information for the
Base class is stored in
the external repository
under the name "base"
...
configuration section.
repository.
class CharacterArray
.
...
factory.
environment division.
data division.
working-storage section.
...
...
method-id. "new".
...
end method "new".
end-factory.
49
50
Chapter 4 Classes
object.
working-storage section.
*>
*>
*>
*>
*>
...
method-id. "sayHello".*> Start of instance
*> method "sayHello"
...
end method "sayHello".*> End of instance method.
end object.
*> End of code for
*> instances.
end class Example.
To see a class outline example that uses the Micro Focus COBOL
alternative syntax, see the section Summary of Syntax Alternatives in
the chapter Micro Focus OO COBOL Alternative Syntax.
Inheritance
Most OO COBOL classes inherit from a superclass. In the Micro Focus
class libraries the only exception to this is the Base class, which is at the
root of the inheritance tree for all other classes in the class libraries.
When you write your own COBOL classes you will nearly always write
them as a subclass either of Base or of another class.
In addition to a subclass inheriting all the methods of the classes above
it in the hierarchy, it can also inherit directly from more than one class;
this is known as multiple inheritance.
If you do decide to write a class which is not a subclass either of Base or
of one of its subclasses, you will not inherit the functions provided by
Base. You will have to implement your own method for destroying
unwanted instances, to replace the "finalize" method in the Base class.
You dont need to implement your own "new " method for creating
new instances, because this method is part of the Behavior class, and is
always available. Behavior is provided in the Base Class Library, and can
Inheritance
Methods
Data
Method Inheritance
A factory object inherits all the factory methods of its superclass, and an
instance inherits all the instance methods of its superclass. Since the
superclass in turn inherits all the factory and instance methods of its
superclass, it follows that an object inherits all the methods
implemented by superclasses all the way up to the root class (usually
Base). When a method is implemented in more than one class in an
heirarchy, then when an object of a class that inherits the method is
executed, it is the method that is lower down in the hierarchy that is
executed.
If a class inherits from a class that also inherits from a class, and if a
method of the same name exists in both superclasses, then when that
method is invoked, the method in the superclass immediately above the
subclass is called.
If a class inherits directly from more than one class (multiple
inheritance), and if a method of the same name exists in more than one
of those superclasses, then when that method is invoked, the method in
the superclass declared first in the Class-ID paragraph of the subclass is
called.
Figure 4-2 shows an object C1 receiving the "setValue" message. Object
C1 is an instance of class C. The superclass of class C is class B, and the
superclass of class B is class A. Classes B and C do not implement instance
method "setValue", so the message gets passed all the way up to class A
where the code for "setValue" exists.
Instance method "getValue" is implemented in both class B and class A.
If object C1 was sent the "getValue" message, it would use the
implementation in class B, as this would be found first. You can always
Object-oriented Programming with COBOL
51
52
Chapter 4 Classes
Figure 4-3 shows a case where an instance object gets sent a message
not implemented in any of its superclasses. The message gets passed up
the inheritance chain until it gets to Base. If Base does not understand
the message either, it sends the message "doesNotUnderstand" back to
the instance which originally received the message.
Inheritance
53
54
Chapter 4 Classes
All factory objects are instances of Behavior. Behavior is part of the Base
Class Library, and can be thought of as a metaclass, or class that
describes behavior common to all classes of object. If the message is an
instance method of Behavior, it is executed. Otherwise, Behavior sends
it to the instance methods of Base. It does this because Behavior is a
subclass of Base.
If no method is found, then Base sends the "doesNotUnderstand"
message back to the object which originally received the message.
Data Inheritance
A factory object inherits all the factory data of its superclass, and an
instance object inherits all the instance data of its superclass. The
Files in OO Programs
inherited data of a subclass includes any data that the superclass itself
inherited from a class higher up the hierarchy. The inherited object data
is initialized when an object is created. The inherited factory data is
allocated independently from the factory data of the inherited class or
classes when the factory of the subclass is created. A subclass can only
access inherited data through the methods it inherited from the same
class. For example, if the class Manager inherits from the class
Employee, and Employee defines the data item:
employeeNumber
PIC 999
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).
Micro Focus COBOL provides alternative syntax and behavior; see the
section Data Inheritance in the chapter Micro Focus OO COBOL
Alternative Syntax.
Files in OO Programs
OO COBOL supports full COBOL file handling syntax, and you can use
this in your classes to read and write to COBOL file types. To do file
handling, you need to include the File Section and a File-Control
paragraph for each file in your factory code or instance code. One or
more of your factory methods or instance methods will contain file
processing verbs such as OPEN, CLOSE, READ.
When the factory or instance source elements of a class contains a file
specification, any subclasses below it in the class hierarchy inherit the
file specification. Each factory or instance object of each of these
subclasses has its own file connector unless the EXTERNAL clause is
55
56
Chapter 4 Classes
specified for the file in the original class. You can use dynamic filename
assignment or file sharing to resolve conflicts in accessing the physical
files associated with these file connectors. For more infomation about
file connectors, dynamic filename assignment and file sharing see your
Language Reference.
To store data global to all instances of the class (instances will only
be able to access this data by sending messages to the class).
To see where the factory source element fits within the class source
element, review the code for an example class in the section Class
Structure.
A factory object can only access data directly that it has declared itself.
A factory object can only access data it has inherited by sending
messages to its superclass.
For further information about data inheritance using ISO 2002 OO
COBOL see the section Data Inheritance. For further information about
data inheritance using Micro Focus alternative syntax see the section
Data Inheritance in the chapter Micro Focus OO COBOL Alternative
Syntax.
Class Initialization
Class initialization code is executed when the class is loaded by the runtime system; it is only ever executed once during an application run.
Class initialization code is optional, and for most classes is not required.
You use it for initializing factory object data. For example, you might
want to make certain objects available to your factory object at startup.
You couldnt specify these in value clauses in your factory WorkingStorage Section because value clauses can only specify static data,
whereas object handles are allocated dynamically at run time.
To write class initialization code, write a factory method called
"initializeClass", and put all the initialization code in that method. The
method will be automatically called by the run-time system when it
loads the class.
Your COBOL system uses demand loading to reduce application startup
times. This means you cant predict exactly when any particular class will
be loaded. A class is guaranteed to be loaded and initialized by the time
it receives its first message. Because you do not know exactly when a
class is loaded, you should not rely on class initialization code to set
values in external variables used elsewhere in the application.
Factory Methods
Factory methods are source elements nested inside the factory object
source element. There is only ever one occurrence of any particular type
of factory object when you run an application, so factory methods are
generally concerned with the creation and management of instance
objects.
57
58
Chapter 4 Classes
Instance Data
You declare instance data in the Working-Storage Section of the
instance object source element. Instance data can only be accessed from
instance methods, and each instance can only see its own instance data.
An instance object inherits all the instance data of its superclass and any
classes higher up the hierarchy.
When an instance is created by an application, the run-time system
allocates an area of memory for the data declared in the WorkingStorage Section, and for instance data declared in any superclasses it
inherits from. For more information about creating instances see the
section Instance Creation Methods in the chapter Methods.
An instance object can only access data directly that it has declared
itself. The only way an instance object can access data it has inherited
from a superclass, is to send a message to the superclass. For further
information about data inheritance using ISO 2002 OO COBOL see the
section Data Inheritance. For further information about data
inheritance using Micro Focus alternative syntax see the section Data
Inheritance in the chapter Micro Focus OO COBOL Alternative Syntax.
You should only declare as instance data the data which is actually part
of an objects attributes. You should declare data items which you need
for temporary working and calculations elsewhere. The safest place to
declare temporary data is in the Local-Storage Section of any methods
which require it.
For example, the only instance data declared for the Account objects
used by the tutorials in this book is the customer name, account number
and balance. If there is a piece of data which is the same for all instances
(for example, the interest rate), it is declared as factory object data. All
temporary data is declared in method Local-Storage Sections as
required.
Every byte of storage you declare as instance data is allocated every
time your application creates a new instance object. Only declaring as
instance data the data which is strictly part of the objects attributes
keeps memory overhead to a minimum.
Instance Initialization
How you code the initialization for an object is largely up to you. There
is no explicit mechanism for instance initialization in the way there is for
class initialization. The easiest and most readable way is to code an
"initialize" method, and to write an instance creation method (which is
always a factory method) which invokes the "initialize" method after it
has created an instance. You can also initialize data in the WorkingStorage Section using VALUE clauses.
Some objects might be initialized from data supplied with the message
that creates them. The instance creation method would have to pass
these parameters to the "initialize" method. Other types of object are
always initialized to the same state at creation. Windows and dialog
boxes usually fall into this category; the initialization code usually
consists of painting them with the same set of gadgets and labels every
time.
59
60
Chapter 4 Classes
Instance Methods
Instance methods are source elements nested inside the instance object
source element. Instance methods are the way in which an application
can alter the state of an object or query its attributes.
Instance methods have access to instance data.
You code factory and instance methods in the same way; the only
difference between them is their position in the class source element
and the scope of data to which they have access. How to code methods
is explained in more detail in the chapter Methods.
Parameterized Classes
A parameterized class is a skeleton class that has one or more formal
parameters. When you provide specific class names or interface names
as actual parameters, the Compiler expands the parameterized class
into a new non-parameterized class.
The purpose of parameterized classes is to make it easier for you to
create many similar classes. For example, if you need four linked list
classes to enable you to store four different types of object, you can
write one parameterized class, then use the expansion feature to create
the four linked list classes at compile time. This is less work than writing
four complete linked list classes.
(In a linked list each item has a link to the next item. Linked lists provide
an easy way of storing and retrieving objects.)
An additional advantage of parameterized classes is that they enable
conformance checking at compile time. If you have a general linked list
that can store any type of object, an object of a different class to the
class your application expects could be added to the table; this could
result in unexpected run-time results. With an expanded parameterized
class, any INVOKE statement trying to add an object of the wrong class
will be caught at compile time by the Compiler.
A parameterized class always has a USING phrase that lists the formal
parameters in its Class-ID paragraph.
Parameterized Classes
You need to specify the EXPANDS phrase in the entry for the class in the
Repository paragraph of any program that uses a class created from a
parameterized class.
For example, suppose that you wanted to create a linked list for
employees who report to a particular manager. The parameterized class
could look like this:
$set repository(update on checking on)
class-id. PLinkList as "PLinkList" inherits Base
using fparam1.
repository.
class fparam1
class Base as "base"
.
factory.
* new: creates new linked list, initialise
* head and tail pointers
method-id. "new".
linkage section.
01 newObject usage object reference PLinkList.
procedure division returning newObject.
invoke super "new" returning newObject
invoke newObject "initlinkedlist"
exit method
end method "new".
end factory.
object.
working-storage section.
* data items to hold head of linked list and position
* during iteration
method-id. "initLinkedList".
local-storage section.
01 tmp-element usage object reference fparam1.
procedure division.
* code to initialize linked list
exit method
end method "initLinkedList".
method-id. "add".
01 newEntry usage object reference LinkEntry.
61
62
Chapter 4 Classes
linkage section.
01 lk-element usage object reference fparam1.
procedure division using by value lk-element.
* code to add the element to the linked list
exit method.
end method "add".
method-id. "getFirst".
local-storage section.
01 tmp-element usage object reference.
linkage section.
01 lk-element usage object reference fparam1.
procedure division returning lk-element.
* code to get the first element from a linked list
exit method.
end method "getFirst".
method-id. "getNext".
local-storage section.
01 tmp-element usage object reference.
linkage section.
01 lk-element usage object reference fparam1.
procedure division returning lk-element.
* code to get the next element from a linked list
exit method.
end method "getNext".
end object.
end class PLinkList.
Parameterized Classes
repository.
class Employee as "Employee"
class Manager as "Manager"
class PLinkList as "PLinkList"
class ELinkList as "ELinkList"
expands PLinkList using Employee.
factory.
...
end factory.
object.
working-storage section.
01 ListEmployees usage object reference ELinkList
value null.
* initManager: initalize linked list
method-id. "initManager".
procedure division.
set ListEmployees to ELinkList::"new"
exit method
end method "initManager".
* AddEmployee: add employee to linked list
method-id. "addEmployee".
linkage section.
01 lk-employee usage object reference Employee.
procedure division using by value lk-employee.
invoke ListEmployees "add"
using by value lk-employee
exit method
end method "addEmployee".
* display : display managers details and all reporting
* employees from linked list
method-id. "display" override.
local-storage section.
01 employee usage object reference Employee.
procedure division.
...
invoke ListEmployees "getfirst" returning employee
perform until exit
if employee not = null
invoke employee "display"
else
exit perform
end-if
63
64
Chapter 4 Classes
65
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.
Net Express:
Net Express provides wizards that help you to create classes, methods
and data quickly. For more information see the Help topics To create a
class, To add a method to a class and To add a data item to a class.
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.
66
Chapter 5 Methods
A method can also have data of its own; you can declare the following
types of storage section in a method:
Local storage
Data items that are local to the current invocation of a method.
Linkage
Data items for passing parameters to and from a method.
aTempItem
linkage section.
01
01
lnkValue
aResult
pic x.
pic x comp-5.
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 doesnt invoke itself directly; it may invoke a
method in a different object which invokes the original method a
second time.
You can put a piece of code used by several different methods into
a method on its own. You can use this method like a subroutine.
You may need to get or change the value of a data item declared in
a superclass. This is possible only if the superclass provides a method
to do this, since methods are always inherited by subclasses. Your
object sends a message to itself to invoke the inherited method and
apply it to its own data.
SELF
SELF enables an object to send a message to itself. The method
invoked is a method in the same class. If you send a message to SELF
from object A, object A is the receiver of the message; if you send a
message to SELF from object C, object C is the receiver of the
message.
SELF always refers to the object currently executing, even if the
method is one which is being inherited. For example, imagine two
objects, A and B, instances of classes A and B where B inherits from
A. A implements instance method, "calculateValue". B implements
instance method, "getObjectConstant". The "calculateValue"
method sends the message "getObjectConstant" to SELF. If B gets
sent the "calculateValue" message, the method invoked is the one
inherited from class A. When "calculateValue" sends a message
"getObjectConstant", the message actually gets sent to the object
B.
67
68
Chapter 5 Methods
SUPER
SUPER enables an object to send a message to itself. The method
invoked is a method in one of the superclasses of the class. If SUPER
is used from an instance, the run-time system searches for a method
beginning with the instance code of the superclass immediately
above the class, and works its way up through the instance methods
of all the superclasses until it finds a method matching the message.
If SUPER is used from a factory method, the run-time system
searches for a factory method beginning with the factory object
code of the superclass immediately above the class and works its
way up through the factory methods of all the superclasses until it
finds a method matching the message.
Micro Focus
extension
SELFCLASS
SELFCLASS enables an instance object to send a message to the
factory object which created it. The method invoked is a method in
the factory object. If you use SELFCLASS from a factory method, it
points to the metaclass for this class, which is an instance of
Behavior.
ISO 2002 OO COBOL provides an alternative to SELFCLASS; this is the
"FactoryObject" method of the ISO 2002 Base class. If you invoke
the "FactoryObject" method on any object that inherits from Base,
it returns the same object reference as SELFCLASS, that is an object
reference pointing to the factory object.
Note: You can also use SELF and SELFCLASS as object reference data
items that you can pass as parameters to other methods.
The 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.
69
70
Chapter 5 Methods
pic x(80).
71
72
Chapter 5 Methods
The Compiler generates get property and set property methods for custno, 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.
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.
73
74
Chapter 5 Methods
75
6 Interfaces
This chapter explains the rules for writing interfaces, with short
examples of code. For full syntax definitions, see your Language
Reference.
Overview
An interface is a set of method prototypes; that is, skeleton methods
with no code. Classes can implement interfaces; a class that implements
an interface must provide full method definitions for the method
prototypes in the interface.
You can develop a hierarchy of inheriting interfaces, similar to a
hierarchy of classes. An interface can inherit from more than one
interface; this is known as multiple inheritance. An inheriting interface
has all the method specifications defined for the inherited interface
definition or definitions, including any method specifications that the
inherited definition or definitions inherited. The inheriting interface
can define new methods augmenting the set of inherited method
specifications. The inheriting interface must always conform to each of
the inherited interfaces.
Net Express:
Net Express provides wizards that help you to create interfaces and
methods quickly. For more information see the Help topics To create a
class and To add a method to a class.
76
Chapter 6 Interfaces
The code block below shows the outline of an example interface source
element. An ellipsis (...) shows where code has been omitted, and
indentation indicates the levels of nesting. In this example the interface
Drivable, containing a method prototype for calculating mileage,
inherits from the interface Rentable, which can be assumed to contain
methods applicable to all objects that can be rented.
interface-id. Drivable
inherits from Rentable. *> Interface identification.
environment division.
...
configuration section.
repository.
interface Drivable
*>
*>
*>
*>
*>
Repository paragraph
names the interfaces this
interface refers to.
Information for the
Drivable interface stored
*>
*>
*>
*>
*>
*>
.
*> Period ends paragraph.
procedure division.
method-id. "calcMileage". *> Start of method
*> prototype "calcMileage".
*> Method contains data
*> but no code.
data division.
linkage section.
01 endMileage pic 9(6).
01 beginMileage pic 9(6).
01 mileage pic 9(6).
procedure division using endMileage, beginMileage
returning mileage.
end method "calcMileage". *> End of method prototype.
method-id. "logDamage".
*> Start of method
*> prototype "logDamage".
end method "logDamage".
*> End of method prototype.
Interface Implementation
Interface Implementation
Factory objects and instance objects within classes can implement
interfaces. The implementing object implements all the method
prototypes defined for the implemented interface definition or
definitions, including any method prototypes that the implemented
definition or definitions inherited.
Here is an example of an instance object that implements the Drivable
interface:
class-id. Car inherits from Vehicle.
configuration section.
repository.
class Car
class Vehicle
interface Drivable
.
factory.
* The code for the factory object starts here
...
* The code for the factory object ends here.
end factory.
*-----The instance object code starts here.
object. implements Drivable.
working-storage section. *> Instance data goes here.
...
procedure division.
interface-methods.
*> Start of implementation
*> of interface methods.
method-id. "calcMileage".
data division.
linkage section.
01 endMileage pic 9(6).
01 beginMileage pic 9(6).
01 mileage pic 9(6).
procedure division using endMileage, beginMileage
returning mileage.
subtract endMileage from beginMileage giving mileage.
end method "calcMileage".
method-id. "logDamage".
...
end method "logDamage".
77
78
Chapter 6 Interfaces
method-id. "pickUp"
...
end method "pickUp"
instance methods.
...
end object.
*-----the instance object code ends here.
end class Car.
Parameterized Interfaces
A parameterized interface is a skeleton interface that has one or more
formal parameters. When you provide specific class names or interface
names as actual parameters, the Compiler expands the parameterized
interface into a new non-parameterized interface. The purpose of
parameterized interfaces is to make it easier for you to create many
similar interfaces.
A parameterized interface always has a USING phrase that lists the
formal parameters in its Interface-ID paragraph.
You need to specify the EXPANDS phrase in the entry for the interface
in the Repository paragraph in any program that uses a interface
created from a parameterized interface.
Here is an outline of the code for a parameterized interface:
interface-id. pinterface using fparam1 fparam2.
repository.
class fparam1
Parameterized Interfaces
class fparam2.
method-id meth1.
procedure division using by reference fparam1.
end method meth1.
method-id meth2.
procedure division using by reference fparam2.
end method meth1.
end interface pinterface.
You can use the MyInterface interface in a procedural program too, but
only indirectly. You need to create a class that implements the interface,
then include entries for both the interface and the class in the
programs Repository paragraph. In the program you can use typed
object references of the MyInterface interface, and use the myInterface
interface in object views, for example:
program-id. prog.
repository.
class A.
class B.
class ClassC implements MyInterface.
*> this class implements MyInterface
interface MyInterface expands pinterface
using ClassA ClassB.
79
80
Chapter 6 Interfaces
...
working-storage section.
1 obj-ref1 usage object reference MyInterface.
1 obj-ref2 usage object reference factory class3.
procedure division.
set obj-ref1 to obj-ref2
invoke obj-ref1 "someMethodInTheInterface" using ...
81
Compiling
The processes for compiling an OO application are very similar to those
described for all COBOL applications elsewhere in your documentation
set.
Use the standard Micro Focus Compiler to compile your OO COBOL
programs.
Compiler Directives
Use the OOCTRL Compiler directive to control behavior that is specific
to OO COBOL programs. This provides a number of options, which you
set on or off by use of the + and - signs respectively, preceding the
option character. The options are:
F
82
You must set the REENTRANT compiler directive on any COBOL class
that can be invoked from more than one thread. This directive
ensures that the class initialization process is handled correctly
when the class is started from more than one thread. Classes
compiled without this directive can fail in unpredictable and
Compiling
Net Express:
83
84
Debugging
Many of the same tools and techniques used for debugging COBOL
applications are applicable to OO COBOL applications. You can animate
the classes in an application in the same way that you can animate any
COBOL program.
When you query an object reference, the Animator displays the object
handle contained in the object reference. This enables you to see
whether object references are pointing to the same or different objects.
An object handle with value x"0000" always refers to the NilObject. An
object handle with the value of x"20202020" is reserved by the run-time
system. Sending messages to it gives the error message "Invalid object
reference".
There are some extra facilities to help you with some debugging
problems that are unique to OO programs:
Debugging
message, then it will execute a method, and your application may fail at
some later point, or give unexpected results.
To prevent reallocation of object handles, set environment variable
OOSW to+d:
Net Express:
set oosw=+d
Server Express:
OOSW=+d
export OOSW
Note: The +d setting for OOSW is intended for development work only.
Do not set +d in a production environment, as the run-time system
could eventually run out of object handles to allocate. The number of
object handles the run-time system can allocate before this happens
depends on the amount of memory available.
85
86
These sorts of problems can occur when you are using reference
modification to access data, or when you pass object data as a
parameter to a method that tries to access it using Linkage Section data
items declared as the wrong size. If you are using the Base class methods
"malloc" and "dealloc" to allocate and free memory, the following
types of error are also trapped:
Net Express:
If any of these types of errors occur when you are running with guard
pages active, you will get run-time error 114; if you are animating the
program execution stops with the statement that caused the problem
highlighted.
You can set the guard pages before or after object data and memory
allocations.
Message Tracing
To set the guard page before object data and memory allocations:
Net Express:
Server Express:
set oosw=+g1
OOSW=+g1
export OOSW
To set the guard page after object data and memory allocations:
Net Express:
Server Express:
set oosw=+g2
OOSW=+g2
export OOSW
Switches +g1 and +g2 are mutually exclusive - you cannot set them both
at the same time.
Note: Running with guard pages on increases the amount of memory
used by your application. Only use it for debugging.
Message Tracing
If you are having problems with finding the point at which an
application fails or raises an exception, you can switch on a message
trace. This can be particularly useful if the error occurs while execution
is in one of the class libraries.
Server Express:
The output is an ASCII file, trace.log, which you can look at with any
ASCII editor.
Net Express:
Click View > Trace Log. The trace information appears in a pane at
the bottom of the Net Express IDE. You can change how many
messages are stored by clicking Options > Trace Log and entering a
new value in Store Messages
Object-oriented Programming with COBOL
87
88
The output is an ASCII file, trace.log, which you can look at with any
ASCII editor.
Every message sent by the application is logged in file trace.log.
Note: Running with trace on slows down application execution as every
message sent is written and flushed to the file.
resolveself
resolvetosuper
Object reference
Message
Object type
Instance object.
Factory object.
Metaclass object.
Class of object
invoked
Class of
implementor
Stack level
Troubleshooting Tips
Troubleshooting Tips
This section deals with the following common problems:
Server Express:
Symbol redefined
89
90
Symbol Redefined
OO programs can cause RTS error 119 (Symbol redefined) for either of
the following reasons:
You have defined a class name with more than one filename
The first of these happens when within a single class you have named
two factory methods the same or two instance methods the same. You
are allowed to use the same names for a factory and an instance
method; you might for example have a class program which defined an
"initialize" method for both the factory and the instance object.
The second usually happens when you have a particular class defined in
the Repository paragraph of different programs, against different
filenames. Filenames are case-sensitive, so you can get this error even if
the names only differ in case.
For example, the Repository paragraph in program A might look like
this:
repository.
class DateClass as "Date"
...
and the Repository paragraph in the DateClass class might look like this:
repository.
class DateClass as "date"
...
Troubleshooting Tips
91
92
93
Part 3: Tutorials
This part contains the following chapters:
94
Part 3: Tutorials
95
Sending messages
A class is an object in its own right; it can have behavior and data of its
own, which is different to the behavior and data of instances of the
class. The main function of most classes is to implement the behavior
needed to create and initialize new instances.
You can use stopwatches to time things. Each stopwatch has methods
to start, stop and reset timing, and to get the current elapsed time.
96
The Stopwatch class factory and instance methods are listed below.
Factory methods
Description
Instance methods
Description
"start"
"stop"
"reset"
"getTimeFormatted"
Sending Messages
Sending Messages
In this section you will create instances of the Stopwatch class, and send
messages to the instances, using the supplied program, timer.cbl.
Program timer.cbl is not an OO COBOL class; it is a piece of procedural
code which uses OO COBOL objects. To communicate with the objects
timer.cbl uses the following OO COBOL syntax:
You will now animate timer to see some simple object behavior. The
code demonstrates the following points:
The factory object has factory data, which is unique to itself, and
not directly available to any of its instances.
The way you can access an objects data is through its methods (by
sending it messages). You cannot read or modify data to which the
object does not explicitly give you access through a method.
To animate timer:
1
97
98
Sending Messages
99
100
Summary
This completes the tutorial on creating objects and sending messages.
You have seen:
At this point you might be thinking that there is nothing special about
objects, and you could have done exactly the same thing using a few
subroutines. This is true, but think about what this would involve.
First you need to define a data structure for recording the start, stop
and elapsed time for a stopwatch. Then timer1.cbl needs to declare this
structure for each stopwatch it is going to use. When you want to start
timing, you call the start subroutine, passing it one of these structures
as a parameter. Similarly when you want to stop, or get the elapsed
time.
Should you decide to alter the implementation of the stopwatch
subroutines, you probably also need to change every place where you
have declared stopwatch data.
Compare this with the situation using objects. You declare an object
reference for each stopwatch, and having declared it, you simply send it
messages to start, stop or give the elapsed time. You can alter the
implementation as much as you want, providing you keep the interface
for the messages the same.
All the implementation details are hidden from you, and each
stopwatch you declare encapsulates its data and implementation into a
single entity. The code for any client of a stopwatch is kept very simple,
enabling you to concentrate on what you want to do with it, rather
than on how to use it.
101
Structure of a class
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:
Identifying a class
Factory methods
Instance methods
102
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.
Move the cursor to the top of the file to see the Class-ID paragraph.
Move the cursor to the end of the file to see the End Class header.
Structure of a Class
It creates a data item for each class named. At run time, this data
item holds an object handle to the factory object.
It enables the run-time system to find and load the file with the
class executable code.
A class is guaranteed to be loaded before the factory object receives
its first message. Usually this occurs when you send the first message
to the factory object, but before the factory object receives it.
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.
103
104
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:
Local-Storage Section
Data items that are local to the current invocation of a method. The
method uses local storage for all its temporary working data. This
has the advantage of supporting recursion.
Linkage Section
Variables passed as parameters to and from the method.
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 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.
Structure of a Class
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 objects 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.
105
106
factory.
working-storage section.
...
method-id. "new".
...
end method "new".
end factory.
object.
*>
*>
*>
*>
working-storage section.
...
method-id. "start".
...
end method "stop".
end object.
This completes the summary of class structure. In the next section you
will animate some of the Stopwatch code.
Step the exit method statement to return from the method back
to timer.cbl.
107
108
Summary
Summary
This concludes this tutorial on writing a class program. In this tutorial
you learned:
109
110
111
Object properties
Object views
Multiple inheritance
Person
Employee
Student
IndPlacement
CharString
112
Scroll to the end of the code.The last two methods in the Employee
class are GETJOBTITLE and SETJOBTITLE. These are methods that
113
114
Close Employee.cbl
Run the supplied shell script persscrp. This compiles all the source
code files for animation.
Step the first statement, which creates a new employee, with data
items name and date of birth. You are now at the first statement of
the method "newEmployee" in employee.cbl. Note that this
statement uses the predefined object reference SUPER to indicate
that the method to be invoked is in the superclass, Person.
Step this statement. You now move up the inheritance chain again,
to Person; you are at the first statement of the method
"newPerson" in person.cbl. Again, this method invocation uses the
predefined object reference SUPER to indicate that the method to
be invoked is in the superclass. The method is the "new" method of
Base, the class from which most classes ultimately inherit.
Step this statement. The "new" method of Base is executed but you
do not go into the source code for Base since it is part of a class
library.
The next statement, the first in the "initPerson" method, uses inline
method invocation to call the newString method of the utility class
CharString, which allocates memory for and creates strings of any
length. The statement:
move CharString::"newstring"(lk-personName) to personName
is equivalent to:
01 tempObject usage object reference CharString
.
.
.
invoke CharString "newstring" using lk-personName
returning tempObject
setpersonName to tempObject
You should now be at the breakpoint that you set in the main
program, personnel.cbl. Step the next statement, which invokes
CharString to create a string for the job title of the employee.
10 Perform Step the next three statements: press P then S three times.
You are now in the set property method for the data item jobTitle.
This is a method that was automatically generated when you
compiled employee.cbl, because jobTitle was defined with the
object property syntax.
11 Step through this method until you return to personnel.cbl.
115
116
12 Scroll down until you find the line below the tag P010:
invoke IndPlacement "newindplacement" using "John White"
"23/07/81"
With the cursor on this line press B then Z to zoom to the cursor
position. A second employee is created, with name, date of birth
and job title.
13 The statement that you have halted on creates an object of class
IndPlacement (industrial placement). This is the class that inherits
from both Employee and Student. Step this statement. You move to
the first statement of the newIndPlacement method of the
IndPlacement class.
14 Step this statement. You might expect this to invoke the
newEmployee method of the Employee class, or the newStudent
method of the Student class. But since both of these call the
newPerson method of the Person class, it makes more sense to call
the newPerson method directly.
15 Press P then S four times. . This creates the new person with name
and date of birth.
16 You should now be back in the main program, personnel.cbl. Press
P, then S. ; this calls CharString to create a string for the job title of
the industrial placement.
17 Step the next statement, which calls CharString to create a string for
the course title of the industrial placement.
18 Press P then S three times.. You are now in another automatically
generated set method, but this time it is a method of the Student
class. It sets the course title of the student - in this case, our
industrial placement.
19 Step through this method until you return to personnel.cbl.
20 The next part of this tutorial illustrates object views. Before we
continue, find the data definition for personTable: position the
cursor on personTable(3) in the next statement and press L then C.
The data definition is:
01 personTable occurs 3 times usage object reference
Person.
117
118
28 Press P then S to execute the next statement in one go. This invokes
the "display" method of the class Person, which displays just the
items that are common to all persons: name and and date of birth.
You can step through the "display" method of Person if you want
to take a closer look at the code).
29 Step through the next two statements, which display "Job title: " in
the Application Output window.
30 Press P then S. This invokes the "displayNl" method of the utility
class CharString, which displays the job title without advancing.
31 Step the next statement. You return to the end of the perform loop
in personnel.cbl.
32 Step the next two statements, then press P then S. This invokes the
"display" method of IndPlacement, because the next object in
personTable is an indPlacement object. You can see the course title
being displayed as well as the name and date of birth.
33 Step the next two statements, then press P then S. This invokes the
"display" method of Person, because the final object in personTable
is a Person object. Only the name and date of birth are displayed.
34 Step to the end of the program.
35 Press B then C to clear the breakpoint you set in step 2.
36 Press Escape to stop the Animator.
Summary
In this tutorial you have learned:
How to use object views to set object references going up the class
hierarchy
119
Person
Employee
Student
IndPlacement
CharString
Motor
Vehicle
Car
PLinkList
LEntry
The first five of these classes were used in the chapter More Complex
Class Tutorial; they have the same functions in this tutorial. To remind
yourself of the relationships between the first four classes see the
120
Person and Car both implement the interface Displayable: this means
that they must both contain a display method to replace the display
method prototype in the Displayable interface.
PLinkList is a parameterized class, that is, a class that has one or more
formal parameters, which are replaced at run time by real parameters.
Parameterized classes allow you to re-use the same code to create many
similar classes. The classes that are created from PLinkList create and
maintain a linked list of objects. LEntry is a class that is used in
conjunction with PLinkList.
CharString, Person, Vehicle and PLinkList all inherit from Base.
Note: Some of the classes in the Pclass application have "finalize"
methods, but for the sake of simplicity these methods are not invoked.
You should always write "finalize" methods for your classes and make
sure you invoke them. Finalize methods destroy objects and release the
Object-oriented Programming with COBOL
resources they were using. For more information on finalizing see the
section Destroying Objects in the chapter Using Objects in Programs.
Open the file Displayable.cbl, the source file for the Displayable
interface, in the Editor. You can see that the interface consists of
just one method, "display", and that this contains no code that does
anything, just headers and an end marker. A method like this is
called a method prototype. An object that implements the
Displayable interface must supply a real "display" method to
replace the prototype. If the method protototype specifies
parameters, the implementing objects must supply methods with
matching parameters.
Scroll down until you come to the line that defines the car object:
object. implements Displayable.
This states that objects of the Car class must be displayable, that is
there must be a method in the Object part of the class that specifies
how Car objects are to be displayed. You can see by scrolling down
that the Car class does indeed include a display method.
Well see how these methods are called when we animate the
application.
5
Close Car.cbl and open the file PLinkList.cbl. The source code begins
with the CLASS-ID header:
class-id. PLinkList as "PLinkList" inherits Base
using fparam1.
121
122
provides the actual parameters. The first entry inside the braces is
the name of the normal class that is generated at compile time,
DLinkList in this case. The second parameter is the name of the class
or interface that the normal class references. In this case we are
using the parameterized class PLinkList to create a normal class
DLinkList that manipulates objects that implement the Displayable
interface.
By specifying a class as the actual parameter, you could use the same
parameterized class to create a normal class that manipulates
objects that are all of the same class.
The next Compiler directive:
constant formalParam "interface"
Close PLinkList.cbl
Run the supplied shell script pclascrp. This compiles all the source
code files for animation.
Scroll down until you find the statement after tag P005:
set car1 to Car::"newcar"("Mini", 4, 6)
The next two statements create two new car objects. Step through
the code for the first object, car1, if you want to see the details of
the object creation process. Otherwise press P then S twice.
Step the next four lines, which illustrate the ability to set object
references to an object that implements an interface. The object
displayItem, defined in pclass.cbl as:
01 displayItem usage object reference Displayable.
The code between tags P015 and P020 show that object views and
the Micro Focus OO COBOL extension, the "INSTANCE OF" syntax,
work with interfaces as well as with classes. Step through this code
if you want to investigate the details. Otherwise scroll down to the
first line of code after tag P020, position the cursor on that line and
press B then Z.
123
124
The next few lines show how the class DLinkList, created from the
parameterized class PLinkList, is used. Press P then S to execute the
statement:
set displayList to DLinkList::"new"
The next four lines add four objects to the linked list by invoking
the "add" method of the DLink List class. These are of disparate
classes, but because they all implement Displayable, they can all be
added to the list. If you attempt to add an object that does not
implement this interface, the Compiler will detect and report the
error as part of its conformance checking.
If you are interested in seeing how the code to add an object to the
linked list works, step the next statement, and all the statements
executed as a result of the method invocation in it.
Position your cursor on the statement after tag P025, and to add
objects to the list.
10 The code between tag P025 and the end of the program displays
each item in the list in turn, calling each objects specific "display"
method. If you are interested in seeing how the code to display an
object in the linked list works, step though the first iteration.
11 Press Z to complete the program. You will see the information
being displayed in the Application Output Window.
12 Press Escape to stop the Animator.
Summary
In this tutorial you have learned:
125
127
128
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
...
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.
object.
object-storage section.
...
method-id. "sayHello".
...
end method "sayHello".
end object.
end class Example.
Shared Data
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
129
130
Data Inheritance
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 ObjectStorage Sections of its superclass. The next two sections explain:
This says that B inherits all the data in A, and that any subclass of B can
also inherit Bs data (which would include As data).
Data Inheritance
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:
Where you have classes inheriting data, they must be compiled from
the top down, starting with the superclass, so that the .ins and .cls
files are available when you compile the subclasses.
The .cls and .ins files for superclasses must either be in the same
directory as classes which inherit their data, or in a directory on your
COBCPY environment variable.
131
132
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.
Data Inheritance
133
134
Extending a Class
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].
Extending a Class
class-object.
end class-object.
object.
end object.
end class a.
Class B:
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.
135
136
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.
137
13 Requirements-based
Vocabulary
Requirements-based vocabulary enables you to define new COBOL
verbs and functions for use with the objects you have created. This
chapter explains the syntax for defining these new verbs and functions.
Requirements-based vocabulary is a Micro Focus extension. All the code
shown in this chapter uses the Micro Focus alternatives to the ISO 2002
syntax.
Overview
As an alternative message-sending mechanism to the INVOKE verb, you
can create your own new COBOL verbs and functions. For example, you
could create a new verb, CREDIT, enabling you to write:
credit aBankAccount with amount
Include the external classes at the start of each program (or class)
which invokes objects through a vocabulary.
138
Defining a Vocabulary
You define vocabularies on a class basis. Each vocabulary is defined by
an external class. An external class is a program that defines a set of
method interfaces, but does not include any code.
Defining a Vocabulary
* Object program.
object.
* Instance methods
end object.
end class BankAccount.
Method Interface
A method program interface definition has the following elements:
Method-ID paragraph
Linkage Section
139
140
Parameters
Compulsory words
Noise words
You can enable the use of both these in verb signatures by setting
compiler directive OOCTRL(-Q). Setting this directive disables the use of
qualification in a verb signature which invokes a method. The default
setting is OOCTRL(+Q).
User-defined Functions
You can also create new functions with user vocabularies. The new
functions look like COBOL intrinsic functions when used in a program.
For example, you could code:
compute interest = .06 * function balance (thisBankAccount)
You can omit the keyword function, so you could also write:
compute interest = .06 * balance (thisBankAccount)
Include the external class defining the new syntax in your program
as a copyfile, using a COPY statement. By convention these are
stored in .if files.
If you are using several objects with their own vocabulary
definitions, you must include the external class for each one. Put
external classes at the top of the source code, before the
Identification Division.
141
142
The Micro Focus class libraries supplied with your COBOL system include
external classes with vocabularies for the following types of
manipulation:.
chararray.if
symbtab.if
Net Express:
guibase.if
Net Express:
sdiframe.if
One advantage that vocabularies give you is that data values are cast
into the format expected by the target method. For example, you can
code:
credit anAccount with 5
143
145
Overview
The following class libraries are supplied:
Base
The Base Class Library provides COBOL classes for basic system
support. It also provides classes for
Java domain
Classes for Java/COBOL interworking.
Net Express:
GUI classes
Classes for creating and managing graphical applications that
exploit the Windows native interface. These include classes for
most of the common controls, including dialog boxes, entry fields,
pushbuttons, list boxes, and tree views.
146
COM
Classes that represent COM documents, servers, clients and controls.
It also has classes which wrap common COM interfaces, enabling
easy access to frequently used COM functions.
Net Express:
COM Component
Classes for working with COM components.
To enable you to recompile and animate the class libraries sometimes this is helpful when debugging your own applications.
To enable you to change the class libraries if you need to (but see
the Warning note at the end of the section Animating the Class
Libraries).
Declare as
Signed integers
Unsigned integers
PIC X COMP-5
Booleans
Booleans
Where TRUE is numeric 1 and FALSE is
numeric 0.
PIC S9(9) COMP-5 and PIC X(4) COMP-5 are both 4-byte data types.
For consistency, we suggest you adopt these conventions when writing
your own classes.
147
148
Frameworks
The class
Private methods are not documented. Methods inherited from Base are
not documented as all objects in the Base class Library inherit these,
except where they have been explicitly overridden. You can see these
methods, which are common to all objects, by looking at the
documentation for the Base class.
Net Express:
Server Express:
From the Net Express Help Contents click Reference, OO Class Library,
Class Library Reference, then click the Class Library Reference icon at
the foot of the help topic.
In the Server Express bookshelf, click Reference Help Topics, OO COBOL,
OO COBOL Class Library Reference.
Frameworks
Frameworks are the way in which different types of object interact
together. Individual class and instance objects have interfaces which
describe the way you communicate with that object.
A framework is a protocol used by several different types of object cooperating to implement a particular function. The other chapters in this
part of the book document the main frameworks used in the class
libraries. For example, the chapter Collection Frameworks describes the
messages a collection sends to its elements.
Base
Net Express:
GUI
Net Express:
COM
We strongly recommend that you only try to animate one or two class
library programs at a time from your application.
The run-time system itself uses the class libraries during startup, so if
you attempt to animate a whole class library you might find yourself
stepping through code in which you are not interested before your
application is loaded.
Net Express:
Click OK.
149
150
This switch tells the run-time system not to load the class library
supplied with Server Express, but to use the individual class library
files you have just compiled. The class library files must either
appear on the path set in the environment variable COBDIR, or in
the current directory from which you run your application.
3
151
15 Collection Frameworks
This chapter introduces the frameworks used by the collection classes in
the Base Class Library. Collection frameworks are mainly concerned
with the communication between collections and the elements they
store.
All the code shown in this chapter uses the Micro Focus alternatives to
the ISO 2002 syntax.
Overview
The COBOL collection classes assume that their elements are objects. A
collection sends messages to its elements to get information such as
the elements size and content. Even when you store intrinsic data (as
opposed to objects), the collection uses the methods implemented in
the intrinsic classes and uses the INVOKE ... AS verb to send messages to
the data.
The elements stored in a collection need to include in their interface
the methods to respond to those messages. Default versions of most of
these are provided in the Base class, but you may want to override
these to provide different or more efficient behavior for particular
types of object.
You will also need to provide methods which conform to a particular
interface for the collection class sort and iterator methods.
152
Indexed or non-indexed
You can access any particular element in an indexed collection by
giving its position. This is similar to using a conventional array. In
non-indexed collections, elements are not stored in a defined order.
Here are some of the collection classes available, with their properties:
Bag
Array
CharacterArray
OrderedCollection
SortedCollection
ValueSet
IdentitySet
Dictionary
IdentityDictionary
Creating Collections
You can create a collection to store either objects (a collection of
references) or intrinsic data (a collection of values). A collection of
references can contain more than one sort of object, whereas a
collection of values is initialized for storing data of a particular type and
length.
Before you create a collection, you need to decide which type to create.
You need to decide:
Clone a template for the intrinsic data from one of the intrinsic data
classes; see the section the section Cloning an Intrinsic Data Class in
the chapter Intrinsic Data.
153
154
Creating Dictionaries
Dictionaries are a special sort of indexed collection, which store keydata pairs (known as associations). In a dictionary, the key is used as the
index when you store or retrieve the data. Dictionaries do not allow you
to store duplicate keys.
Like the other collection types, you can store either objects or intrinsic
data in a dictionary. In a dictionary though, either the key or the data
part can be an intrinsic or an object. This gives you the following
possible combinations for intrinsic or object storage:
If the keys are objects, they must provide methods for hashing and
equality comparisons. Objects like CharacterArray already provide these
methods, but if you are using your own types of objects as keys, you
need to provide your own mechanisms.
When you create a dictionary you have to give it a template so that it
knows how the key and data portions are to be stored. The template is
either the Association class, or a clone of the Association class.
The Association class is another clonable class, like the classes for
intrinsic data classes, used for creating templates for data storage. An
Association template actually consists of two templates; one for the key
and one for the data. To create any type of dictionary you need to
create an Association template.
Having created a template for your dictionary object, there are two
methods you can use to create a dictionary itself; "ofValues" or
"ofAssociations". A dictionary "ofValues" stores each element as a key
data pair. A dictionary "ofAssociations" stores each element as an
instance of the Association template you used to create the dictionary.
local-storage section.
01 aKeyTemplate
object reference.
01 aDataTemplate
object reference.
01 anAssocTemplate
object reference.
01 aDictionary
object reference.
01 aLength
pic x(4) comp-5.
...
00020
00028
00029
00030
00031
00032
00033
procedure division.
...
move 3 to aLength
invoke CobolCompX "newClass" using aLength
returning aKeyTemplate
move 20 to aLength
invoke CobolPicX "newClass" using aLength
returning aDataTemplate
155
156
00034
00035
00036
00037
00038
00039
Lines 1-6
Lines 28-29
Line 31-32
Line 34
Line 37
where:
zString
aCharArray
Object reference
aLiteral
where:
aCharArray
157
158
Equality
Equality
A collection compares two elements by sending the "equal" message to
one element, giving it the other element as a parameter. The default
"equal" method in Base simply compares the object references of the
two objects (that is, they are equal only if they are the same object).
For many applications you will want to compare part or all of the
elements instance data to determine equality. Implement the interface
to "equal" as follows:
method-id. "equal".
linkage section.
01 lnkElement
object reference.
01 lnkEqualityResult
pic x comp-5.
88 isEqual
value 1.
88 isNotEqual
value 0.
procedure division using lnkElement
returning lnkEqualityResult.
* Code to compare lnkElement to self and return
* lnkEqualityResult.
exit method.
end method "equal".
Hashing Elements
You may need to implement this method so that two objects can
compare themselves using part of their instance data. Use the following
interface to implement the "lessThanOrEqual" method:
method-id. "lessThanOrEqual".
...
linkage section.
01 lnkString
object reference.
01 lnkResult
pic x comp-5.
88 isEqual
value 1.
88 isNotEqual
value 0.
procedure division using lnkString returning lnkResult.
* Code to compare lnkElement to self and return a result
exit method.
end method "lessThanOrEqual".
Hashing Elements
The dictionary and set classes use hash values to store and retrieve
elements. The default "hash" mechanism in Base returns the object
reference to the object.
159
160
You will often need to override the default with a hash mechanism
which creates a hash value using the objects instance data. There are
two reasons for this:
Separate objects that have the same value must always return identical
results from "hash". Hash values do not have to be unique for each
element, but the more duplicate hash values a dictionary contains, the
less efficient its storage and retrieval of elements. Hash values should
always be positive numbers.
Display Mechanisms
There are two mechanisms you can use to display the contents of a
collection. You can send the message "display" to the collection or you
can display the collection on a Listbox.
Display on a Listbox
You can display a collection of CharacterArrays or intrinsic data by
passing it to a Listbox with the "setContents" message. The Listbox
displays each element of the collection as a string on a separate line.
161
162
Iterator Methods
The collection classes implement four iterator methods which enable
you to access all the elements of your collection by sending a single
message to the collection. To use any of the iterator methods you need
to provide a Callback object. The Callback is passed each element of the
collection as a parameter in turn.
This section shows you the interface the method in the Callback must
have to work with the iterator methods. The iterator methods provided
are:
"do"
"select"
"reject"
Iterator Methods
"collect"
163
164
165
16 Intrinsic Data
This chapter explains how you can send messages to the types of
intrinsic data supported by the Base Class Library, and how you can
write classes to support other types.
All the code shown in this chapter uses the Micro Focus alternatives to
the ISO 2002 syntax.
Overview
The Base Class Library includes a set of classes corresponding to some of
COBOLs intrinsic data types. Objects from these classes correspond to
COBOL data items. This enables you to store and manipulate intrinsic
data in object-oriented ways.
The intrinsic data mechanism is used by the collection classes to store
intrinsic data without creating objects for every item of intrinsic data in
the collection. You can think of intrinsic data as being static objects
whose data is allocated by the Compiler at compile time; all other
objects in Micro Focus OO COBOL are dynamic and their data is
allocated at run time.
The three COBOL data types supported by the Class Library are:
PIC X(n)
166
The supplied intrinsic classes can only store data of a preset length. If
you want to use them for intrinsic data of any other length, you must
first clone the class, creating a new class for the length of data you
require.
Data Length
COBOLPICX
1 byte
COBOLCOMP5
4 bytes
COBOLCOMPX
4 bytes
To store different length data you need to clone the class for a different
length. To do this, send the message "newClass" to one of the intrinsic
data classes, supplying the length as a parameter. It returns a class
capable of storing data of the length given with the "newClass"
method.
For example:
move 6 to aLength
invoke cobolPICX "newClass"
using aLength
returning aNewPicXClass
where:
aLength
aNewPicXClass
You can use cloned classes as templates for INVOKE...AS, and for
creating collections of intrinsic values. You can also create instances of
intrinsic classes using the "new" method.
working-storage section.
01 aValue
pic x(2) comp-5.
01 cloneX2Class
object reference.
01 aLength
pic x(4) comp-5.
...
procedure division.
...
move 2 to aLength
invoke COBOLCOMP5 "newClass" using aLength
returning cloneX2Class
...
invoke aValue as cloneX2Class "hash"
returning aHashValue
...
Declaring data.
Lines 16-18
Line 19
167
168
storageRequirements
"baseClass"
Returns the object handle to this class object.
"maximumSize"
Returns the maximum number of bytes allowable for this type of
intrinsic data. For example, a COMP-X data item cant be more than
eight bytes long, so the "maximumSize" method in the
COBOLCOMPX class returns eight.
object reference.
The "baseClass" method returns the object handle of the named class,
rather than SELF, so that the correct handle is returned for the baseClass
even when the message is sent to a clone of your intrinsic class.
Code the method interface for "maximumSize" like this:
method-id. "maximumSize".
linkage-section.
01
lnkSize
pic x(4) comp-x.
procedure division returning lnkSize.
* Code to return the maximum allowable size.
exit method.
end method "maximumSize".
"equal"
"lessThan"
"greaterThan"
These are the methods for comparing objects with intrinsic data items:
"equalByLengthValue"
"lessThanByLengthValue"
"greaterThanByLengthValue"
169
170
instanceData
pic x.
pic x comp-x.
value 1.
value 0.
object reference.
pic x comp-x.
value 1.
value 0.
pic x(4) comp-x.
pic x occurs 1 to maxSize
* set isFalse.
exit method.
end method "equalByLengthValue".
171
172
173
17 Callback Frameworks
This chapter shows you how to create Callback instances, and how you
can use them in your own applications.
All the code shown in this chapter uses the Micro Focus alternatives to
the ISO 2002 syntax.
Overview
An instance of the Callback class contains an object and the name of a
method. When you send the message "invoke" to the Callback, it sends
a message to the object it contains, invoking the named method.
A Callback instance is like a pointer to a block of code. It enables you to
pass a block of code to a class or object method for later execution. For
example, to implement an exception handling method, you create a
Callback containing the method and pass the Callback to the
ExceptionHandler.
The Base Class Library also contains a class called EntryCallback which
enables you to create a Callback to any COBOL entry point. You can use
an EntryCallback with Class Library objects anywhere you can use a
Callback, enabling you to use Class Library functionality like collection
iterators with procedural COBOL code. All the rules for using Callbacks
apply equally to EntryCallbacks.
Using Callbacks
There are two stages to using Callbacks:
174
When you are using Callbacks with Class Library objects, you only need
to know how to create the Callback instance. The instance is then
passed to the Class Library object, which invokes it when needed.
However, you might want to use Callbacks in the classes you write, so
this chapter also shows you how can invoke a Callback.
Creating a Callback
To create a Callback object, send the "new" message to the Callback
class. You must supply the object that implements the method you want
written into the Callback, and the message name to invoke the method.
Terminate the message name with a null byte (x"00). The Callback
"new" method looks for a null to find the end of the message name.
You can add a null byte to a literal very easily with the syntax shown
below:
01 wsLiteral
*> equivalent to
aCallback
[p1]...[p6]
Invoking a Callback
You do not need to know how to invoke Callbacks in order to use them
with the objects in the supplied Class Library, but you may want to use
Using Callbacks
175
176
177
18 Exception Handling
Frameworks
Exception handling is the mechanism by which objects raise and trap
errors. This chapter shows you how you can use this mechanism in the
objects you write.
All the code shown in this chapter uses the Micro Focus alternatives to
the ISO 2002 syntax.
Overview
Exception handling gives you a flexible mechanism for handling errors
in OO COBOL programs. When an object traps an error, it raises an
exception. Each different kind of error is represented by a different
exception number.
Objects in the supplied class libraries react to error conditions by raising
exceptions. The Class Library has a set of exception numbers, and a file
of error messages. You can define your own exception conditions for
objects you create, associating each set of exception conditions with its
own error messages file.
An object raises an exception by sending itself the "raiseException"
message, passing an exception number as a parameter. The Base class
implements the "raiseException" method, so it is inherited by all
objects. Exception handlers trap errors raised by objects through the
"raiseException" mechanism; they do not trap run-time system errors.
The ExceptionManager class in the Base Class Library provides most of
the logic for actually handling exceptions, including a system exception
handler. The system exception handler displays an error message and
shuts down the application when an object raises an exception, but an
application can define its own exception handlers and attach them to
individual classes or objects to redefine their behavior.
178
You can replace the system exception handler with a system exception
handler of your own.
"error-message-text"
where:
nnnnn is the exception number
"error-message-text" is the text of the error message you wish to
output for this exception number.
The double-quote character (") is assumed to be the quote character set
in the $quote statement above. You can change quote statements at
any point during the .err file; each change applies to all the messages
which follow it up until the next $quote statement. You can also enter
comments, by starting a line with a $ followed by a space. Here is an
example:
$quote "
$
$set 1
1 "Invalid key type"
2 "Failed to open file for dictionary"
3 "Using a key of different size"
4 "Record exceeds maximum allowed length"
5 "Error reading control record"
6 "Indexed file has wrong key structure"
7 "Key not found in file"
8 "Attempt to write a record which has been deleted"
...
$ ************************************************************
$ Last modified on 95/08/01
$ ************************************************************
Net Express :
Next, add the .err file to the project for your application. The IDE
compiles this to a .lng file.
Right-click on the .lng file, and package it as a Micro Focus library (.lbr)
file. Name the library file filenamedf.lbr. For example, an error message
file you refer to in your source code as myerrors has the filename
myerrorsdf.lbr.
Server Express:
Run the shell script, mfmsg to create a .lng file and copy it into the
message directory structure under $COBDIR/lang/. You need to be
logged in as the superuser to run this script successfully. To run the shell
script:
mfmsg output.lng input.err
179
180
The offset value returned depends on how many other message files
have been previously registered during the application run. Never hardcode an error file offset value into your classes; always query the
ExceptionManager for the value.
To register an error file:
invoke ExceptionManager "registerMessageFile"
using library errfile
returning anOffset
where:
library
errfile
anOffset
Server Express:
The library name is ignored by the mechanisms which find the message
file. It is still used by the ExceptionManager as part of the registration of
the message file. You must use the same value for both parameters
when you send a "queryMessageFile" message to the
ExceptionManager referring to the same file. Although the first
parameter is not strictly needed on Server Express, including it as part of
the method interface keeps source code compatibility between Server
Express and Net Express.
The example below is a method that registers an error message file with
the ExceptionManager.
method-id. "registerFile".
local-storage section.
01 errorFile
01 libraryFile
01 anOffset
pic x(8)
pic x(6)
pic x(4) comp-5.
procedure division.
move spaces to libraryFile, errorFile
move "mylibf" to libraryFile
move "err-file" to errorFile
invoke ExceptionManager "registerMessageFile"
using libraryFile errorFile
returning anOffset
exit method.
end method "registerFile".
Raising an Exception
Raising an Exception
Whenever a method detects an error (for example, a value out of
range) it should raise an exception. Each different exception has an
exception number relating it to a message in an error message file.
Before raising the exception, you add the error file offset to the
exception number to get a unique exception ID. The object raising the
exception may not be the object which registered the error message
file, so it can query the ExceptionManager to get the offset for its
associated error file. It then raises the exception by sending itself the
"raiseException" message.
The "raiseException" method is implemented in the Base class and is
inherited by all subclasses. If no exception handler is registered for the
object, the system exception handler displays the exception number and
error message, then terminates the application.
If you have registered an exception handler for the object, execution
returns to the statement following the "raiseException" after your
exception handler has been invoked.
In order of descending priority, the ExceptionHandler will try to call
exception handlers registered with:
1
To raise an exception:
1
Get the error message file offset for this type of object, by sending
the "queryMessageFile" to the ExceptionManager
181
182
"raiseExceptionWithTextZ"
"raiseExceptionWithTextCollection"
Queries the ExceptionManager for the exception offset for the error
message file. The exception method either needs to know the name
of the error message file, or the object raising the exception must
implement a method to return it.
Subtracts the error file offset from the exception ID to get the
exception number.
Once the exception method has the exception number, it should test it
to see if it has a value it expects. If it doesnt recognize the error, it
should reraise the exception. The exception can then be trapped either
by an exception handler that knows what to do with it, or by the system
exception handler, which terminates your application.
183
184
errorNumber
lsOffset
linkage section
01 anObject
01 anExceptionId
01 aDataItem
01 aTextCollection
object reference.
pic x(4) comp-5.
object reference.
object reference.
where:
anObject
anExceptionId
aDataItem
185
186
to display the exception number with an error message, then end the
program.
You can replace the system exception method with your own. Create a
Callback for an exception method. Then send the "setSystemHandler"
message to the ExceptionManager.
The "setSystemHandler" method returns you a handle to a CallBack for
the existing system exception handler. If your replacement system
exception method gets an exception it does not know how to handle,
reraise the exception, and the default SystemHandler will actually still
get invoked.
The example below shows you how to replace the system exception
method:
invoke ExceptionManager "setSystemHandler" using newHandler
returning oldHandler
where:
newHandler
oldHandler
187
19 Component Frameworks
This chapter describes the component framework. This provides a
mechanism for communication between objects that is an alternative
to the sending of messages.
All the code shown in this chapter uses the Micro Focus alternatives to
the ISO 2002 syntax.
Overview
The component framework provides a mechanism which enables you
to treat objects like pluggable components. Once you have defined an
object as a component, you can:
The input socket of a component does not have to define behavior for
every signal it might receive when connected to the output of another
component.
When a component sends a signal, it doesnt send it to a particular
object. It sends it to all the components that are connected to it. Each
component that receives a signal can either ignore it or respond to it.
Figure 19-1 shows an interface component using signals to
communicate with database and application components.
188
This is different to the situation with a message, where you must specify
a single destination object when you send a message. If you dont
specify a valid object, or specify one that doesnt understand the
message, the application breaks. With the component mechanism, you
can define objects (or groups of cooperating objects) which act as
common building blocks. You then build your application by plugging
together groups of components.
At every stage of creating and connecting components, you can use
requirements-based vocabulary that we supply. For more information
about using vocabularies see the chapter Requirements-based
Vocabulary.
component must have a unique name. Before you can define output
signals for an object, you must make it into a component.
To make an object into a component, send it the "makeComponent"
message. Include the following statement somewhere in the objects
initialization code.
make component
where:
signalId
189
190
signals
signal new-signal
signal open-signal
signal save-signal
signal exit-signal
exit-signal
new-signal
open-signal
save-signal
value
value
value
value
z"001".
z"002".
z"003".
z"004".
where:
socketName
Having defined an input socket, you need to map all the signals you
expect to receive on that input socket to methods in the component.
The socket name and signal names are all declared as level-78 data
items in a copyfile (see the previous section).
Connecting Components
where:
signalId
socketName
methodName
Connecting Components
Output signals and input sockets only do anything when they are
connected together. You can connect an output component to any
number of input sockets, and any input socket can be connected to the
outputs of more than one component.
191
192
where:
output
input
socketId
Sending Signals
When a component sends a signal, if it is connected to an input socket
which recognizes that signal, it invokes the method defined by the
input socket. You might have the component connected to separate
input sockets on different components, in which case all input sockets
which recognize that signal invoke methods. Methods are invoked in
the order that the components were connected together.
You can optionally send one object handle as a parameter with a signal.
This enables you to send some data with the signal. Sometimes you
want to send a signal which is a request for data; in this case, the
receiving component should define a signal for sending the data back.
For example, an interface component might request a list of customer
accounts for display, by sending a "retrieve-accounts" signal. The
retrieval component receives this signal, and if it finds the data, sends a
"display-accounts" signal, with the account information as data. The
SymbolTable class in the Base Class Library enables you to package up
Sending Signals
where:
signalId
dataBlock
This code uses vocabulary defined in base.if. You must put this as a
copyfile at the beginning of your program to use the SIGNAL verb.
SIGNAL is alternative syntax to:
invoke self "signal" using
signalId dataBlock
193
194
195
197
20 Inheritance Tutorial
This tutorial is intended to demonstrate how inheritance works in OO
COBOL. It uses the example of different types of bank account, and
shows how they can inherit common behavior from a single class, while
adding new behavior or changing as necessary for individual types of
account.
This tutorial uses Micro Focus alternatives and extensions to the ISO
2002 OO COBOL syntax.
This tutorial consists of the following sessions:
1
Account
CheckAccount
Subclass of Account which adds behavior for checking accounts
(checks overdraft limit on withdrawals)
SavingsAccount
Subclass of Account which adds behavior for savings accounts (pays
interest)
HighRateAccount
Subclass of SavingsAccount which adds a method for checking for a
minimum starting balance to open an account
Object-oriented Programming with COBOL
198
Push the Prfm Step keys, then the Step key again. Execution
switches to the line below tag A001 in the Account class.
CheckAccount does not implement the "openAccount" method, but
inherits it from Account.
199
200
201
202
21 Step through the rest of the code until you get to tag B008 of
Bank1.
This code demonstrates the use of polymorphism between objects
descended from a common class. All account types implement the
"printStatement" method in order to print out a statement suitable
for the different account types.
22 Step through the code to print the statements.
23 When Animator displays the "Stop run encountered..." message,
press Esc to exit.
Summary
This concludes the tutorial on inheritance. In this tutorial you learned:
203
Collections
Using Intrinsics
Dictionaries
Iterator Methods
Collections
In this session you will animate a simple COBOL program, coll0.cbl
which illustrates some of the differences and similarities between the
main types of collection. The program is not an OO COBOL class
204
program, but procedural COBOL code which uses the Class Library
collection objects.
For an explanation of the different types of collection, see the section
Different Categories of Collection in the chapter Collection
Frameworks.
To animate coll0.cbl
1
Collections
Press P then E.
This completes execution of the perform loop without you needing
to step through each statement in turn.
205
206
Collections
How does a collection object find out the value of an element? If all
the elements are objects, doesnt this break object encapsulation?
207
208
Using Intrinsics
In the previous session, you looked at a program which stored objects in
different types of collection. There may be occasions when you want to
store intrinsic COBOL data, like numbers, in collections. You can do this
by using the intrinsic classes of the Base Class Library.
Micro Focus OO COBOL provides a mechanism that enables you to send
a message to an intrinsic data item, as though it were an object, using
the INVOKE...AS statement.
Before you can send messages to intrinsic data, you have to clone an
intrinsic class to create a new class for the type and length of intrinsic
data you are using. The Base Class Library includes classes for three
different types of intrinsic data (PIC X, PIC X COMP-X, PIC X COMP-5).
These classes are templates which handle data of fixed length. When
you clone the class, you specify the actual size of data you want to
handle.
We will now look at a short sample program, coll1.cbl, which uses the
intrinsic classes to store a set of integers in an array.
To animate coll1.cbl
1
Dictionaries
This completes this part of the tutorial on using intrinsic data. For more
information, see the chapter Intrinsic Data.
Dictionaries
In this session you will animate through some code which uses a
dictionary to store account objects. The account objects are the ones
which were introduced in the Inheritance Tutorial
For more information about dictionaries, see the section Creating
Dictionaries in the chapter Collection Frameworks.
209
210
Step the two statements below tag A040 (move length of...).
The dictionary we want to create uses the customer name as the
key, and account objects as values. This code clones the intrinsic
class CobolPicX to create a class for representing strings the same
length as a customer name.
Step the two statements below tag A050 (set wsNull to null).
This code clones the Association class, to create a template for the
dictionary. The key portion represents strings the same length as
wsCustomer, the data portion is set to null and represents an object
handle.
Perform Step (press P then S) the statements below tag A070 (move
spaces to wsCustomer).
This creates a check account. Using Perform Step saves animating
through all the "openAccount" code.
Iterator Methods
Iterator Methods
This session shows how coll2.cbl uses the iterator methods to carry out
operations on all accounts. The instructions below assume that you are
continuing directly from the end of the previous section, and have not
stopped animating coll2.cbl.
For more information about iterator methods, see the section Iterator
Methods in the chapter Collection Frameworks.
211
212
Summary
Summary
This tutorial covered the following:
Intrinsic data
Dictionaries
Callbacks
213
214
215
Raising an exception
Raising an Exception
An object raises an exception when it has trapped an error. The objects
in the supplied class libraries define approximately ninety exception
conditions altogether.
The ExceptionManager class provides most of the logic for actually
handling exceptions, including a default exception handler. The
default exception handler displays an error message and shuts down
the application when an object raises an exception, but an application
can define its own exception handlers and attach them to individual
classes or objects to redefine their behavior.
An object raises an exception by sending itself the "raiseException"
message, passing an error number as a parameter. The Base class
implements the "raiseException" method, so it is inherited by all
objects.
The error number is used to identify a message from an error file; it is
also passed to an exception handler for the object if one is registered.
216
Run the supplied shell script exepscrp to compile all the programs
and classes needed for this tutorial.
Move the text cursor down to the first statement below tag B010
(move "Mike" to aCustomer), and press R then C to reset to the
cursor postion.
The first statement in this program registers an exception handler.
You will look at this code later in this tutorial, so for now we skip
over it.
Raising an Exception
The way you compile and package error files is described in the
chapter Exception Handling Frameworks.
Each exception must have a unique numeric identifier, but when
you write an error message file for a set of classes, you dont
necessarily know what application those classes will be used in, and
what other message files will be in use.
The registration mechanism provided by the ExceptionManager
enables you to number your messages starting from 1. Then, when
you register a message file you are returned an offset. Each message
is then identified by adding its number in the file to the offset to
create a unique exception number. We dont need to store the
offset, since we can fetch it from the ExceptionManager when it is
needed.
8
217
218
Next you will animate through the code which sets exception handlers
for the Account classes in the Bank application.
To animate the exception registration code
1
In the next session, you will look at the exception handler method, and
see how it deals with an exception raised by the account classes.
219
220
Press Z.
Execution halts inside the "onExceptionAccountError" method of
AccountExceptionHandler.
Step the statement below tag E060 (if lsException < 4).
The exception handler must now determine what type of exception
has been raised in order to take the appropriate action. If the
exception type isnt one it knows how to deal with, it raises the
exception again (see the code below tag E080).
More sophisticated exception handlers take different action
depending on the type of exception; this exception handler simply
categorizes account exception numbers between one and three as
being those it understands, and those of four or greater as
exceptions to be raised again.
Step through the application until you see the Stop Run message
from Animator.
221
222
Summary
In this tutorial you learned how to:
Raise an exception
223
23 Requirements-based
Vocabulary Tutorial
Requirements-based vocabulary enables you to create new verbs and
functions related to types of application you are working on. This
tutorial demonstrates this feature, using the bank account classes
introduced in the chapter Inheritance Tutorial.
This tutorial uses Micro Focus alternatives and extensions to the ISO
2002 OO COBOL syntax.
This tutorial consists of the following sessions:
1
224
Put the cursor on the statement copy account.if and press AltF2=library to view account.if.
The class-id header at the start of account.if defines it as an
external class. The Compiler does not generate any code for
external classes.
This is the end of the first session. In the next session you will look at
some code which uses the new syntax.
Step through the code of bank2.cbl until you reach tag B008.
As you step through the code, you can see how the same verbs can
be used for SavingsAccounts and CheckAccounts.
225
226
Step through the code until you reach the stop run statement.
Summary
This tutorial covered the following:
How new verbs are defined and made available to client programs
How to use the verbs defined for a set of classes.
227
Part 7: Appendices
This part contains the following chapters:
229
A Descriptions of OO Run-time
Switches
This appendix describes the available switches for the OO support in
the run-time system. Each entry describes the effect of the switch when
it is set on. The default setting that applies if you do not explicitly set
any of these switches is also given.
All OO RTS switches are set in the environment variable OOSW. Specify
a minus "-" before a switch to turn it off, and a plus "+" to turn it on.
You can concatenate several switch settings into OOSW at a time. For
example:
OOSW=-v+d
export OOSW
Debug switch.
lfilename
+g1
+g2
230
List of Switches
d - Debug Switch
Enables debugging by preventing reuse of object handles from finalized
objects.
Properties:
Remarks:
Default:
-d
+ftrace.log
Setting this switch to -f also has the effect of naming the log file
trace.log.
Default:
-g1
You cannot set +g1 and +g2 at the same time. Only set +g1 when
debugging as it increases memory overhead.
List of Switches
This switch is not available on all UNIX platforms. Check the release
notes for your platform.
Default:
-g2
You cannot set +g1 and +g2 at the same time. Only set +g2 when
debugging as it increases memory overhead.
This switch is not available on all UNIX platforms. Check the release
notes for your platform.
Default:
+lclass
Set the class library load switch to -l to disable loading of the class
libraries. You can use this if you want to animate classes (see the section
Animating the Class Libraries in the chapter Introduction to the Class
Libraries).
If you have your own class library in a .lbr file, you can load that instead
of the Micro Focus class libraries. Set:
+lfilename
You can load more than one class library with the +l switch; separate
the names with colons ":". For example:
+llib1:lib2
231
232
t - Trace File
Generate a trace file showing every message sent by your application.
Properties:
Remarks:
Default:
-t
A trace file shows you the messages sent by your application and is
useful for debugging. Do not set this switch when running production
applications: trace slows down execution, and the log file will grow in
size continuously while the application runs.
233
Index
A
ACTUAL-PARAMS Compiler directive 62, 79,
81
ALIGN Compiler directive 81
Animating
class libraries 149
Associations 154
Attributes 22
Automatically growable collections 152
B
Base class 28, 50, 54
Base Class Library 145
Behavior class 50, 54, 69, 85
Binding
dynamic 25
Browse tool 18
C
Callback frameworks 173
Called program not found RTS error 90
CASE Compiler directive 81
Character arrays 156
Class libraries 28, 145
animating 149
Classes 23, 47
declaring 34
extending 134
initialization 57
intrinsic data 168
parameterized 60
structure 48, 127
tutorial 101
Class-id 102
.cls file 83, 131
CobolComp5 class 166
CobolCompX class 166
CobolPicX class 166
"collect" method 163
Collection frameworks 151
tutorial 203
COM Class Library 145
COM Component Class Library 145
Comparison
elements of collection 158
Compiler directive
ACTUAL-PARAMS 62, 79, 81
ALIGN 81
CASE 81
FASTCALLS 81
FASTLINK 81
FIXOPT 81
OO program 81
OOCTRL 81, 129
PARAMCOUNTCHECK 81
RDFPATH 81
REENTRANT 81
REPOSITORY 41, 81
SERIAL 81
Compiling
OO program 81
Component Framework 187
Conformance checking 35, 39, 40, 60, 78
Connecting components 191
Object-oriented Programming with COBOL
234
D
Data
factory objects 56
inheritance 54, 130
instance objects 58
methods 65
DATA IS PRIVATE clause 131
DATA IS PROTECTED clause 130
Data item
PROPERTY clause 72
Debugging
OO program 84
DECLARE SOCKET verb 190
"deepFinalize" method 44
DEFINE SIGNAL verb 188
Demand loading 57
Development
OO programs 18
Dictionaries 154
tutorial 209
Direct data inheritance 130, 132
compilation 83
Display mechanisms
collections 160
"do" method 162
Duplicate elements
collections 152
Dynamic binding 25
Dynamic filename assignment
OO programs 55
E
Elements of collection
comparison 158
Encapsulation 26
Entry points
creating callback 173
EntryCallback class 173
Environment variable
OOSW 85, 87, 229
Equality comparisons 158
Error handling 177
Error message files
creating 178
registering 179
Exception handler 182
Exception handling 177
tutorial 215
Exceptions
raising 181
Extension
class 134
EXTERNAL clause 55
External repository 34, 41
F
Factory
data 103
methods 57, 103
Factory objects 23, 48, 103
data 56, 57
data inheritance 54
method inheritance 51
writing 56
"FactoryObject" method 68
FASTCALLS Compiler directive 81
FASTLINK Compiler directive 81
File
.cls 83
.if 141
.ins 83
.cls 131
.ins 131
trace.log 87
File connectors 55
File handling
OO programs 55
File sharing 55
235
Files
OO programs 55
"finalize" method 43
Finalized object references 44
FIXOPT Compiler directive 81
Framework
component 187
Frameworks 148
Callbacks 173
collection 151
exception handling 177
Function signature 139
G
Garbage collection 43
Get property methods 40, 71
"getNumberOfObjects" method 85
Guard pages 86
GUI Class Library 145
H
Hash mechanisms
collections 159
Hierarchy of classes 27, 50
Hierarchy of interfaces 75
I
.if file 141
Implementation
interface 75, 77
Indexed collections 152
Inheritance 27, 50, 75
data 54, 130
methods 51
polymorphism 29
tutorial 197
Initialization
classes 57
instance objects 59
Inline method invocation 39
tutorial 111
Input socket 190
.ins file 83, 131
Instance methods 60
Instance objects 23, 48, 104
creating 42, 69
data 58
data inheritance 54
initialization 59
method inheritance 51
writing 58
Interfaces 25, 40, 75
inheritance 29
parameterized 78
polymorphism 29
tutorial 119
Intrinsic data 165
storing 153, 154
tutorial 208
INVOKE statement 39
INVOKE...AS statement 167
ISO 2002 COBOL 17, 127
Iterator methods 162
tutorial 211
J
Java domain Class Library 145
Java support Class Library 145
L
Linkage Section
OO program 65
Object-oriented Programming with COBOL
236
Local-Storage Section
OO program 65
M
MAKE COMPONENT verb 188
Manually growable collections 152
MAP SIGNAL verb 190
Memory exceptions 89
Memory leaks 43
finding 85
Message
send 97
Messages
sending 25, 38
sending to intrinsic data 167
tracing 87
Metaclass 50
Method
interface definition 139
Method definition
PROPERTY clause 72
Method prototypes 24, 25, 75
Method selector 26
Methods 24, 65
data 65
exception handler 183
executing 25, 38
factory 57, 103
inheritance 51
inline invocation 39
instance 60
invocation 89
invocation using object properties 40, 71
parameter types 147
parameters 66
Working-Storage Section 129
Micro Focus OO COBOL 17, 127
Multiple inheritance 28, 50, 131
interfaces 75
methods 51
tutorial 111
Object-oriented Programming with COBOL
N
"new" method 42, 69
"newClass" method 166
NIL predefined object reference name 68
Non-indexed collections 152
NULL predefined object reference name 68
Null-terminated literals 174
O
Object data guard pages 86
Object handles 35, 69, 84
preventing reallocation 84
reallocation 44
Object properties 40, 71
syntax 73
tutorial 111
Object reference names
predefined 67
Object references 35
finalized 44
querying 84
Object views 37
tutorial 111
Object-oriented analysis and design 19
Object-oriented COBOL
syntax 17
Objects 22, 33
canceling exception registration 185
creating 42, 69
destroying 43
passing 37
registering with exception handler 185
storing 153, 154
Object-Storage Section 86, 129
OO COBOL
RTS switches 229
toolbar 18
OO wizard 18
OOCTRL Compiler directive 81, 129
237
P
PARAMCOUNTCHECK Compiler directive 81
Parameter types
methods 147
Parameterized classes 60
tutorial 119
Parameterized interfaces 78
Parameters
methods 66
Polymorphism 29, 37
Predefined object reference names 67
Private data 131
Private interfaces 147
Procedures 22
Program not found RTS error 90
PROPERTY clause
data item definition 72
method definition 72
Protection violations 89
Public interfaces 147, 148
S
"select" method 162
SELF predefined object reference name 67
SELFCLASS predefined object reference name
68
Sending messages 25, 38, 97
Sending signals 192
SERIAL Compiler directive 81
Set property methods 40, 71
SET statement 37
Shared data 128, 129
Signal 187
SIGNAL verb 192
Socket 187
Sort methods
collections 161
Subclasses 27, 50
SUPER predefined object reference name 68
Superclasses 27, 50
Symbol redefined RTS error 90
Syntax
comparison 127
System exception method 185
T
R
RDFPATH Compiler directive 81
REENTRANT Compiler directive 81
"reject" method 162
Relative value comparisons 158
REPOSITORY Compiler directive 41, 81
Repository paragraph 34
Requirements-based vocabulary 137
tutorial 223
RTS switches
OO COBOL 229
trace.log file 87
Tracing messages 87
Tutorial
collections 203
dictionaries 209
exception handling 215
inheritance 197
interfaces 119
intrinsic data 208
iterator methods 211
more complex class 111
parameterized classes 119
requirements-based vocabulary 223
simple class 101
238
U
Universal object references 35, 39
Untyped object references 35
User-defined function
creating 141
V
Verb signature 139
Vocabulary
see Requirements-based vocabulary
W
WITH DATA phrase 130
Wizard
OO program 18
Working-Storage Section 86, 103
classes 128
ISO 2002 COBOL 129
methods 129
OO program 65