This chapter describes the key concepts supported by an object-oriented 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.
OO COBOL provides the following elements, which are typical of any OO programming language:
These together provide the three characteristics that define an OO language:
The following sections describe these elements and characteristics in turn, and how they are implemented in OO COBOL.
An object is a combination of data and the procedures to operate on that data. The data is known as the object's 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.
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 change the internals of how the object represents and operates on data, without affecting the rest of the system.
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 class's own data and behavior. The class does not have the same behavior as the instances it creates. A class is like a printer's 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.
Figure 2-2: A Class and Instances Created
From It
Note: Micro Focus COBOL provides alternative terminology and features:
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 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 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).
A message is the way you request an object to perform a service. A message always consists of the following:
Messages may also optionally contain input and output parameters. Where there is an output parameter, the sender will be expecting a reply to its message.
The object reference enables the run-time system to find the object for which the message is intended. The target of a message is known as the receiver. The COBOL run-time system uses dynamic binding to determine the receiver of a message. This means that the receiver of a message is determined at run time rather than at compile time.
The method selector is the text of the message; it tells the receiver which method it should invoke. OO COBOL uses the INVOKE verb to send messages. Figure 2-3 shows the components of a message both diagramatically and in OO COBOL syntax.
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 object's 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 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
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-6.
Many OO languages, including OO COBOL, also provide interface inheritance. This enables you to build up hierarchies of interfaces. Interface inheritance, like class inheritance, helps to reduce coding effort.
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:
Where a number of subclasses inherit from a class, the methods in the class can be method prototypes, that is methods that don't contain any code. Complete methods of the same name appear in each subclass, and these can be different.
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.
For example, consider a graphics drawing system that has objects representing squares and objects representing circles. Circle objects and square objects both have the method draw, either because both are descended from a class that has the method draw, or because both implement an interface Drawable that has the method draw. The code for drawing squares and circles are different, but the display controller can send the message draw to any graphical object, without caring what type it is. The receiver of the message will execute its own draw method, producing the correct result (see Figure 2-6).
Copyright © 2004 Micro Focus International Limited. All rights reserved.