Chapter 21: 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. The Account Classes
  2. Some Simple Account Transactions

The Account Classes

This section introduces the Account classes used in this tutorial. We will use the Net Express development environment to explore the code in these classes, before debugging it in the second session of this tutorial.

There are four account classes altogether:

Exploring the Account Classes Code

To explore the account classes codes, follow these steps:

  1. Start the Net Express development environment.
  2. Click File > Open, and open Examples\Net Express IDE\Bank\inherit.app. You'll see the .cbl files in the project window.
  3. Rebuild all the files in the project.
  4. Display the Browse window: click Search > Browse.
  5. Click on the plus (+) sign next to base to see the Account subclass.
  6. Click on the plus (+) sign next to account to see its subclasses.

    Account has two subclasses, CheckAccount and SavingsAccount. SavingsAccount has further subclasses, indicated by the plus sign (+) in the Browse window.

  7. Click on the plus (+) sign next to SavingsAccount to see its subclasses.

    You can now see that there are four types of account class: Account, CheckAccount, SavingsAccount and HighRateAccount. The hierarchy view shows that the Account class is the superclass of all other account types. The Account class implements the behavior common to all the different types of bank account.

  8. Display just methods in the Browse window: click on the push buttons at the top of the Browse pane so that only the Methods button is shown depressed.
  9. Select Account to see the methods implemented by the account class.

    Account has two class methods, "openAccount" and "setNextAccountNumber", and several instance methods. These include methods for all the things you would expect to be able to do with a bank account, like "deposit" and "withdraw".

  10. Select SavingsAccount.

    The SavingsAccount class implements far fewer methods than Account. It has no method for opening accounts, depositing or withdrawing money. It inherits all the code for these methods from Account. It does have a method to add interest, because this is not behavior common to all types of account. It also has an implementation of "printStatement". All the account classes have their own implementation of "printStatement", because every different type of account prints a different type of statement. This is an example of polymorphism.

These classes also contain methods that are not used at all in this tutorial. The reason is that these classes are also used in the GUI programming tutorial; see the chapter GUI Programming Tutorial .

In the next session, you will use the Bank program to see how inheritance works in these classes. This is a simple program which creates accounts and sends messages to them.

Simple Account Transactions

In this session you will debug bank1.cbl, to see some simple account transactions and how inheritance works in practice. The instructions below assume that you are continuing directly from the previous section and still have the Browse window open with the account classes.

To debug bank1:

  1. Click Debug > Start Debugging then click OK

    This loads bank1.int for execution. You are now in bank1.cbl. The first group of statements (below tag B001) creates a new CheckAccount for a customer

  2. Step through the first three statements.

    When you step invoke CheckAccount, execution switches to the "initializeClass" method of the Account class. The method is used in this case to execute some code for setting up error handling. For more information about class initialization see the section Class Initialization in the chapter Classes.

    This code is the subject of another tutorial, so we execute it without debugging it.

  3. Click . (This is equivalent to clicking Debug > Run Thru.) Then Step the Exit Method statement. Execution switches to the line below tag A001 in the Account class. CheckAccount does not implement the "openAccount" method, but inherits it from Account.
  4. Step the statement:
    invoke super "new"
    .

    This sends the "new" message to this object, but tells the run-time system to start looking for methods in the code for the superclass of Account (class Base). It returns an instance of CheckAccount.

  5. Step the Invoke statement below tag A002.

    This takes you to the "setNextAccountNumber" method of Account.

  6. Step the first statement of this method.

    Data item nextAccountNumber is declared with a value of 0. When the account class or any of its subclasses is initially loaded this data item is set to 0. The method "setNextAccountNumber" tests this value, and if it is zero, sets an initial value. This is the first time the CheckAccount class has received the "openAccount" message, so nextAccountNumber needs initializing.

  7. Step the next statement.

    Execution switches to the "getFirstAccountNumber" method of CheckAccount. In this case, self refers to the CheckAccount class object; although we were executing code implemented by the Account class, the original "openAccount" message was sent to the CheckAccount class object, which inherited its "openAccount" method from Account.

    This method returns a value for the "openAccount" method to start numbering accounts. Each of the subclasses of Account starts account numbers from a different value, and they all implement "getFirstAccountNumber" to return the starting value.

  8. Step through the code up until and including the Exit Method statement.

    This takes you back to the Exit Method statement of "setNextAccountNumber".

  9. Step the Exit Method statement.

    This returns you to the "openAccount" method.

  10. Step the next statement.

    The object handle to the newly created account object is in lsAccount. The "initAccount" method sets the account attributes with a name, balance and account number.

  11. Step through the code up until and including the Exit Method statement.

    This takes you back to the Exit Method statement of "openAccount".

  12. Step the Exit Method statement.

    Execution returns to Bank1, which now has an object handle to an instance of the CheckAccount class.

  13. Step the two statements below tag B002.

    This deposits $1000 in the CheckAccount instance. Again, the code for this is all in the Account class.

  14. Step through the Account code until you return to the statement below tag B003 in Bank1.
  15. Step through the two statements below tag B003.

    These withdraw $50 from the CheckAccount instance. This time the Invoke switches execution to code inside CheckAccount. This is because the CheckAccount class implements its own "withdraw" method, which checks the withdrawal against the value allowed for the overdraft.

  16. Step the statements below tag C010.

    If the withdrawal were to exceed the overdraft set for this instance of CheckAccount, the object would raise an exception (error condition). In this case, the withdrawal amount is OK, so execution proceeds as normal.

    The application in this case has not registered an exception handler to deal with account exceptions, so if an exception occurred the error would get trapped at the system level which would display the error number and halt application execution. Example applications used in some of the other OO COBOL tutorials also use these account classes, but register an exception handler to deal with this type of error.

  17. Step through the application until you reach tag B007.

    Each time you open a type of account which Bank1 hasn't used before, you have to step through the code to get an initial account number. Also, each time you open a type of account which Bank1 hasn't used before, the class initialization code is executed, because it is impossible to know whether other types of account have been opened since the application started running, and therefore whether the class initialization code has already been run.

    As you execute the code, you will see that most of the code for the different types of bank account is inherited from the Account class, with only some methods being implemented in the subclasses.

    The subclasses all inherit from the Account class with data (see the Class-Id statements at the top of each program). This means that as well as inheriting the methods of Account, they also have direct access to the data items declared in account. All the different account types can access variables balance, aName and accountNumber.

    Without the With Data clause in the Class-Id statement of the Account subclasses, they could not access this data directly. Instead, they would have to send messages to the superclass to access this data. The programmer of the Account class would have to implement methods which respond to these messages.

  18. Step the statements below B007 to open a HighRateAccount. This takes you to tag H010 of HighRateAccount. HighRateAccount implements its own version of "openAccount", to check the amount of cash being used to open the account. But once it has verified this, it still uses the "openAccount" method of Account, by sending a message to "super".
  19. 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. Each account type implements a "printStatement" method in order to print out a statement suitable for the account type.

  20. Step through the code to print the statements.
  21. Click Debug > Stop Debugging to stop the Debugger.

Summary

This concludes the tutorial on inheritance. In this tutorial you learned:


Copyright © 2009 Micro Focus (IP) Ltd. All rights reserved.