Chapter 37 Quiz: Object-Oriented COBOL

Test your understanding of OO COBOL concepts including CLASS-ID, METHOD-ID, INVOKE, inheritance, interfaces, and object-oriented design patterns. Each question has one correct answer unless otherwise stated. Try to answer each question before revealing the answer.


Multiple Choice

Question 1

Which paragraph declares the name of a class in OO COBOL?

A) PROGRAM-ID B) CLASS-ID C) OBJECT-ID D) FACTORY-ID

Show Answer **B) CLASS-ID** The CLASS-ID paragraph appears in the IDENTIFICATION DIVISION of a class definition and declares the class name. PROGRAM-ID is used for procedural programs. OBJECT-ID and FACTORY-ID are not valid COBOL paragraphs -- OBJECT and FACTORY are sections within a class.

Question 2

What is the purpose of the REPOSITORY paragraph in an OO COBOL program?

A) It stores object instances for later retrieval B) It declares external class names used by the program C) It defines the location of source code files D) It specifies the version control system for the class

Show Answer **B) It declares external class names used by the program** The REPOSITORY paragraph in the CONFIGURATION SECTION registers the external class names that the program or class will reference. Without this declaration, the compiler cannot resolve class names used in INVOKE statements or object reference declarations.

Question 3

Which statement is used to call a method on an object in OO COBOL?

A) CALL B) PERFORM C) INVOKE D) EXECUTE

Show Answer **C) INVOKE** The INVOKE statement is the OO COBOL mechanism for calling methods on objects or factory methods on classes. CALL is used for procedural subprogram calls. PERFORM is used for paragraph/section execution within a program. EXECUTE is not a valid COBOL statement.

Question 4

Where are factory methods defined within a class?

A) In the OBJECT paragraph B) In the FACTORY paragraph C) In the ENVIRONMENT DIVISION D) In a separate program

Show Answer **B) In the FACTORY paragraph** Factory methods are defined within the FACTORY section of a class. They are class-level methods that can be invoked using the class name rather than an object reference. The most common factory method is `New`, which creates and returns new instances of the class.

Question 5

Given the following declaration, what does WS-ACCT-REF represent?

       01  WS-ACCT-REF       USAGE OBJECT REFERENCE Account.

A) A copy of an Account object B) A pointer to an Account object in memory C) A numeric identifier for an Account D) An inline Account data structure

Show Answer **B) A pointer to an Account object in memory** An OBJECT REFERENCE is essentially a pointer or handle that refers to an object instance in memory. It does not contain the object data itself -- it contains the address of the object. Multiple references can point to the same object, and setting a reference to NULL releases the association.

Question 6

What happens when a subclass defines a method with the same name as a method in its parent class?

A) A compilation error occurs B) Both methods are available and the caller must specify which to use C) The subclass method overrides the parent method for instances of the subclass D) The parent method is permanently replaced for all classes

Show Answer **C) The subclass method overrides the parent method for instances of the subclass** This is method overriding. When a subclass provides its own implementation of a method defined in the parent class, the subclass version is invoked for instances of the subclass (and its subclasses). The parent class method remains unchanged for instances of the parent class. This is the foundation of polymorphism.

Question 7

Which clause is used to establish an inheritance relationship between classes?

A) EXTENDS B) IMPLEMENTS C) INHERITS D) DERIVES

Show Answer **C) INHERITS** The INHERITS clause on the CLASS-ID paragraph establishes that a class inherits from a parent class. For example: `CLASS-ID. SavingsAccount INHERITS Account.` This is distinct from languages like Java (extends) or C# (: BaseClass). OO COBOL uses the INHERITS keyword.

Question 8

What is the primary purpose of the SELF reference in OO COBOL?

A) It refers to the class definition itself B) It refers to the current object instance within a method C) It refers to the parent class D) It refers to the calling program

Show Answer **B) It refers to the current object instance within a method** SELF is an implicit reference available within instance methods that refers to the object on which the method was invoked. In a factory method, SELF refers to the factory object. SELF is commonly used in factory methods to invoke the runtime's built-in "NEW" method for object allocation: `INVOKE SELF "NEW" RETURNING LS-NEW-OBJ`.

Question 9

How do you declare that a class implements an interface in OO COBOL?

A) Using the IMPLEMENTS clause on CLASS-ID B) Using the INHERITS clause on CLASS-ID C) By listing the interface in the REPOSITORY paragraph D) By defining matching method signatures in the OBJECT paragraph

Show Answer **A) Using the IMPLEMENTS clause on CLASS-ID** A class declares interface implementation through the IMPLEMENTS clause. For example: `CLASS-ID. SavingsAccount INHERITS Account IMPLEMENTS InterestBearing.` The class must then provide implementations for all methods declared in the interface.

Question 10

What is the difference between an INTERFACE-ID and a CLASS-ID?

A) There is no difference; they are interchangeable B) INTERFACE-ID defines a contract with no implementation; CLASS-ID defines a complete class with data and methods C) INTERFACE-ID is for factory classes; CLASS-ID is for object classes D) INTERFACE-ID is an older syntax replaced by CLASS-ID

Show Answer **B) INTERFACE-ID defines a contract with no implementation; CLASS-ID defines a complete class with data and methods** An interface (INTERFACE-ID) declares method signatures without providing implementations or data storage. It defines a contract that implementing classes must fulfill. A class (CLASS-ID) provides both data definitions and method implementations. Multiple classes can implement the same interface, enabling polymorphism without requiring a common base class.

Question 11

Which of the following correctly invokes a factory method Create on the class Customer and stores the result?

A) CALL Customer "Create" RETURNING WS-CUST-REF B) INVOKE Customer "Create" RETURNING WS-CUST-REF C) PERFORM Customer "Create" RETURNING WS-CUST-REF D) SET WS-CUST-REF TO Customer::Create

Show Answer **B) `INVOKE Customer "Create" RETURNING WS-CUST-REF`** Factory methods are invoked using the INVOKE statement with the class name (not an object reference) as the target. The method name is specified as a string literal. CALL is for procedural subprograms, PERFORM is for paragraphs, and the double-colon syntax is not valid COBOL.

Question 12

In OO COBOL, where is instance data (object attributes) defined?

A) In the FACTORY WORKING-STORAGE SECTION B) In the OBJECT WORKING-STORAGE SECTION C) In the PROGRAM-ID WORKING-STORAGE SECTION D) In the LINKAGE SECTION of each method

Show Answer **B) In the OBJECT WORKING-STORAGE SECTION** Instance data is defined in the WORKING-STORAGE SECTION within the OBJECT paragraph. Each object instance gets its own copy of this data. Factory data (class-level data shared across all instances) is defined in the FACTORY WORKING-STORAGE SECTION. LINKAGE SECTION items in methods are parameters, not persistent attributes.

Question 13

What does dynamic dispatch mean in the context of OO COBOL?

A) Methods are compiled at different times depending on usage B) The method that executes is determined at runtime based on the actual object type, not the declared reference type C) Objects are allocated dynamically using ALLOCATE D) Method calls are dispatched to different threads for parallel execution

Show Answer **B) The method that executes is determined at runtime based on the actual object type, not the declared reference type** Dynamic dispatch is the mechanism that enables polymorphism. When INVOKE is called on an object reference, the runtime determines which method implementation to execute based on the actual type of the object, not the type declared for the reference variable. This allows a reference typed as a base class to invoke overridden methods on subclass instances.

True/False

Question 14

True or False: In OO COBOL, a class can inherit from multiple parent classes simultaneously.

Show Answer **False** OO COBOL supports single inheritance only. A class can inherit from at most one parent class using the INHERITS clause. However, a class can implement multiple interfaces, which provides a form of multiple type conformance without the complications of multiple implementation inheritance.

Question 15

True or False: The INVOKE statement can be used to call both factory methods and instance methods.

Show Answer **True** INVOKE is used for both factory method calls (using the class name as the target, e.g., `INVOKE Account "New"`) and instance method calls (using an object reference as the target, e.g., `INVOKE WS-ACCT-REF "GetBalance"`). The syntax is the same; only the target differs.

Question 16

True or False: An object reference declared as USAGE OBJECT REFERENCE Account can hold a reference to a SavingsAccount instance if SavingsAccount inherits from Account.

Show Answer **True** This is the foundation of polymorphism. A reference typed as a base class can hold a reference to any subclass instance. A `SavingsAccount` IS-A `Account`, so it can be assigned to an `Account` reference. Methods invoked through this reference will dispatch to the `SavingsAccount` implementations via dynamic dispatch.

Question 17

True or False: The FACTORY paragraph can contain WORKING-STORAGE data items.

Show Answer **True** The FACTORY paragraph can include a DATA DIVISION with a WORKING-STORAGE SECTION. Data items defined here are class-level (static) data, shared across all instances. This is useful for tracking class-wide information such as instance counts or shared configuration values.

Question 18

True or False: You must use the INVOKE statement to access instance data from outside the class.

Show Answer **True** OO COBOL enforces encapsulation. Instance data defined in the OBJECT WORKING-STORAGE is private to the class. External code cannot directly reference these data items. To access or modify instance data, the class must provide getter and setter methods, which are called via INVOKE.

Question 19

True or False: An interface in OO COBOL can contain data definitions.

Show Answer **False** Interfaces (INTERFACE-ID) define only method signatures. They cannot contain data definitions, WORKING-STORAGE items, or method implementations. An interface is purely a contract specifying which methods an implementing class must provide.

Question 20

True or False: Setting an object reference to NULL releases the object from memory immediately.

Show Answer **False** Setting an object reference to NULL releases the reference association, but does not necessarily free the object from memory immediately. If other references still point to the object, it remains alive. Even when all references are released, the actual memory reclamation is implementation-dependent and may be deferred to a garbage collection cycle or runtime cleanup phase.

Question 21

True or False: OO COBOL was first introduced as part of the COBOL 2002 standard.

Show Answer **True** Object-Oriented COBOL features were formally standardized in the ISO COBOL 2002 standard. Some vendors provided proprietary OO extensions before 2002 (notably Micro Focus and IBM), but the standardized CLASS-ID, METHOD-ID, INVOKE, and related syntax became part of the official language specification with the 2002 revision.

Code Analysis

Question 22

What is wrong with the following class definition?

       IDENTIFICATION DIVISION.
       CLASS-ID. Temperature.

       IDENTIFICATION DIVISION.
       OBJECT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-DEGREES         PIC S9(3)V9.
       01  WS-SCALE           PIC X VALUE "C".
       PROCEDURE DIVISION.

       IDENTIFICATION DIVISION.
       METHOD-ID. GetCelsius.
       DATA DIVISION.
       LINKAGE SECTION.
       01  LS-RESULT          PIC S9(3)V9.
       PROCEDURE DIVISION RETURNING LS-RESULT.
       GET-IT.
           IF WS-SCALE = "C"
               MOVE WS-DEGREES TO LS-RESULT
           ELSE
               COMPUTE LS-RESULT =
                   (WS-DEGREES - 32) * 5 / 9
           END-IF
           .
       END METHOD GetCelsius.

       END OBJECT.
       END CLASS Temperature.
Show Answer The class definition is missing the **FACTORY paragraph**. Even if the factory has no custom methods, the structure requires the FACTORY section to be present in most OO COBOL implementations. Without a factory, there is no way to create instances of the class (no `New` factory method). Additionally, the class is missing the **ENVIRONMENT DIVISION** with a **REPOSITORY paragraph** that should declare the `Temperature` class name. A corrected skeleton would include:
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       REPOSITORY.
           CLASS Temperature.

       IDENTIFICATION DIVISION.
       FACTORY.
       PROCEDURE DIVISION.
       *> Factory methods (including New) go here
       END FACTORY.

Question 23

Examine the following code and determine what value is displayed:

       WORKING-STORAGE SECTION.
       01  WS-BASE-REF       USAGE OBJECT REFERENCE Account.
       01  WS-FEE             PIC 9(5)V99.

       PROCEDURE DIVISION.
           INVOKE SavingsAccount "New"
               RETURNING WS-BASE-REF
           INVOKE WS-BASE-REF "GetMonthlyFee"
               RETURNING WS-FEE
           DISPLAY WS-FEE
           STOP RUN.

Assume: - Account.GetMonthlyFee returns 15.00. - SavingsAccount inherits from Account and overrides GetMonthlyFee to return 5.00.

Show Answer The displayed value is **00005.00**. Although `WS-BASE-REF` is declared as `OBJECT REFERENCE Account`, the actual object stored in it is a `SavingsAccount` instance (created by `INVOKE SavingsAccount "New"`). Due to dynamic dispatch (polymorphism), the INVOKE call to `GetMonthlyFee` executes the `SavingsAccount` version of the method, which returns 5.00. The declared reference type does not determine which method runs -- the actual object type does.

Question 24

What is the output of the following code?

       WORKING-STORAGE SECTION.
       01  WS-REF-A          USAGE OBJECT REFERENCE Counter.
       01  WS-REF-B          USAGE OBJECT REFERENCE Counter.
       01  WS-VAL-A           PIC 9(8).
       01  WS-VAL-B           PIC 9(8).

       PROCEDURE DIVISION.
           INVOKE Counter "New" RETURNING WS-REF-A
           INVOKE WS-REF-A "Increment"
           INVOKE WS-REF-A "Increment"
           INVOKE WS-REF-A "Increment"

           SET WS-REF-B TO WS-REF-A

           INVOKE WS-REF-B "Increment"
           INVOKE WS-REF-B "Increment"

           INVOKE WS-REF-A "GetValue" RETURNING WS-VAL-A
           INVOKE WS-REF-B "GetValue" RETURNING WS-VAL-B

           DISPLAY "A: " WS-VAL-A
           DISPLAY "B: " WS-VAL-B
           STOP RUN.
Show Answer The output is:
A: 00000005
B: 00000005
The key insight is that `SET WS-REF-B TO WS-REF-A` copies the **reference**, not the object. Both `WS-REF-A` and `WS-REF-B` now point to the **same** Counter object. The first three increments bring the count to 3. The next two increments (via WS-REF-B) operate on the same object, bringing the count to 5. Both `GetValue` calls return 5 because they query the same underlying object.

Question 25

Identify the design problem in this class hierarchy:

       CLASS-ID. Vehicle.
       *> Methods: StartEngine, StopEngine, GetFuelLevel,
       *>          Accelerate, Brake, GetSpeed

       CLASS-ID. Car INHERITS Vehicle.
       *> Methods: OpenTrunk, SetAirConditioning

       CLASS-ID. Bicycle INHERITS Vehicle.
       *> Methods: RingBell, SetGearRatio
Show Answer The design violates the **Liskov Substitution Principle**. A `Bicycle` inherits `StartEngine`, `StopEngine`, and `GetFuelLevel` from `Vehicle`, but bicycles do not have engines or fuel. Any code that works with a `Vehicle` reference and calls `StartEngine` will behave incorrectly or nonsensically when given a `Bicycle` instance. The fix is to redesign the hierarchy. One approach: create a more general `Vehicle` base class with only universally applicable methods (`Accelerate`, `Brake`, `GetSpeed`), and create a `MotorizedVehicle` subclass that adds `StartEngine`, `StopEngine`, and `GetFuelLevel`. `Car` inherits from `MotorizedVehicle`, and `Bicycle` inherits directly from `Vehicle`. Alternatively, use interfaces: `IMotorized` (for engine-related methods) and `IVehicle` (for movement-related methods). `Car` implements both; `Bicycle` implements only `IVehicle`.

Question 26

What problem does this factory method have, and how would you fix it?

       IDENTIFICATION DIVISION.
       METHOD-ID. New.
       DATA DIVISION.
       LINKAGE SECTION.
       01  LS-NAME            PIC X(30).
       01  LS-BALANCE         PIC 9(9)V99.
       01  LS-NEW-ACCT        USAGE OBJECT REFERENCE Account.
       PROCEDURE DIVISION
           USING LS-NAME LS-BALANCE
           RETURNING LS-NEW-ACCT.
       CREATE-ACCT.
           INVOKE SELF "NEW" RETURNING LS-NEW-ACCT
           MOVE LS-NAME TO WS-ACCT-NAME
           MOVE LS-BALANCE TO WS-ACCT-BALANCE
           .
       END METHOD New.
Show Answer The factory method attempts to directly access instance data (`WS-ACCT-NAME` and `WS-ACCT-BALANCE`), which are defined in the OBJECT WORKING-STORAGE. **Factory methods cannot directly access instance data** -- they are in a different scope (the factory scope vs. the instance scope). The fix is to invoke an initialization method on the newly created object:
       CREATE-ACCT.
           INVOKE SELF "NEW" RETURNING LS-NEW-ACCT
           INVOKE LS-NEW-ACCT "Init"
               USING LS-NAME LS-BALANCE
           .
Then define an `Init` method in the OBJECT section that receives the parameters and populates the instance data.

Question 27

Analyze the following code and explain why it will not compile:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TestProgram.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-ACCT-REF       USAGE OBJECT REFERENCE Account.
       01  WS-BAL             PIC 9(9)V99.

       PROCEDURE DIVISION.
           INVOKE Account "New" RETURNING WS-ACCT-REF
           INVOKE WS-ACCT-REF "GetBalance"
               RETURNING WS-BAL
           DISPLAY WS-BAL
           STOP RUN.
Show Answer The program is missing the **ENVIRONMENT DIVISION** with a **CONFIGURATION SECTION** containing a **REPOSITORY paragraph** that declares the `Account` class. Without the REPOSITORY entry, the compiler does not recognize `Account` as a class name and cannot resolve the object reference declaration or the INVOKE statements. The fix is to add:
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       REPOSITORY.
           CLASS Account.
before the DATA DIVISION.

Question 28

Review this method and explain what subtle bug exists:

       IDENTIFICATION DIVISION.
       METHOD-ID. Transfer.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-TEMP-BAL        PIC 9(9)V99.
       LINKAGE SECTION.
       01  LS-TARGET-REF      USAGE OBJECT REFERENCE Account.
       01  LS-AMOUNT          PIC 9(9)V99.
       01  LS-SUCCESS          PIC 9.
       PROCEDURE DIVISION
           USING LS-TARGET-REF LS-AMOUNT
           RETURNING LS-SUCCESS.
       DO-TRANSFER.
           INVOKE SELF "GetBalance" RETURNING WS-TEMP-BAL
           IF WS-TEMP-BAL >= LS-AMOUNT
               INVOKE SELF "Withdraw" USING LS-AMOUNT
               INVOKE LS-TARGET-REF "Deposit" USING LS-AMOUNT
               MOVE 1 TO LS-SUCCESS
           ELSE
               MOVE 0 TO LS-SUCCESS
           END-IF
           .
       END METHOD Transfer.
Show Answer The bug is a **lack of atomicity**. The method checks the balance, performs a withdrawal, and then performs a deposit as three separate operations. If the `Deposit` method on the target account fails for any reason (for example, the target reference is NULL, the target account is closed, or a system error occurs), the money has already been withdrawn from the source account but never deposited into the target. The funds are effectively lost. The fix is to either: (1) check for error conditions on the target account before withdrawing, (2) wrap the operations in error handling that reverses the withdrawal if the deposit fails, or (3) use a transaction coordinator that ensures both operations succeed or both fail (compensating transaction pattern). Additionally, `LS-SUCCESS` is not initialized to 0 at the start, though the IF/ELSE structure covers both paths.

Scoring Guide

Score Level
25-28 Expert -- You have mastered OO COBOL concepts
20-24 Proficient -- Strong understanding with minor gaps
15-19 Intermediate -- Good foundation, review advanced topics
10-14 Developing -- Review inheritance, polymorphism, and design principles
Below 10 Beginning -- Revisit the chapter material before proceeding