123456* pclass: interfaces and parameterized classes
      *
      * person class and all sub classes implement the interface
      * Displayable
      *
      * Unrelated class Car also implements the interface
      * Displayable
      *
      * The demo also uses a parameterized class which has been
      * compiled to allow only objects whose classes implement
      * the Displayable interface
      *
      $set repository(checking on)
       identification division.
       program-id. pclass.

       repository.
           class Person as "Person"
           class Employee as "Employee"
           class IndPlacement as "IndPlacement"
           class Car
           interface Displayable as "Displayable"
           class CharString as "String"
           class PLinkList as "PLinkList"
           class DLinkList as "DLinkList"
                           expands PLinkList using Displayable
           property jobTitle
           property courseTitle
           property listSize
           .

       working-storage section.

       01 displayItem usage object reference Displayable.
       01 emp1 usage object reference Employee.
       01 emp2 usage object reference Employee.
       01 indPlace1 usage object reference IndPlacement.
       01 car1 usage object reference Car.
       01 car2 usage object reference Car.
       01 noItems usage binary-short value 0.
       01 displayList usage object reference DLinkList.
       01 person1 usage object Reference Person.
       procedure division.
      *
      * Create some objects to use later
      *

      * Employee 1

           invoke Employee "newemployee" using "George Brown"
                                               "12/02/1957"
                                         returning emp1

           set jobtitle of emp1 
               to CharString::"newstring"("Senior Analyst Programmer") 


      * Industrial Student 1

           invoke IndPlacement "newindplacement" using "John White"
                                                       "23/07/81"
                                              returning indPlace1

           set jobTitle of indPlace1
               to CharString::"newstring"("Junior Programmer")

           set courseTitle of indPlace1
               to CharString::"newstring"("Physics")

      * P005. Create new car objects

           set car1 to Car::"newcar"("Mini", 4, 6)
           set car2 to Car::"newcar"("Audi", 2, 6)

      * object reference of Displayable can hold any class implementing
      * displayable interface.
      * The Car class implements the interface Displayable directly. 
      * See the line object. implements Displayable in Car.cbl
      * Employee and IndStudent classes inherit Person class which
      * implements the Displayable interface
      * P015. Object references for Displayable objects

           set displayItem to indPlace1
           set displayItem to car1
           set displayItem to car2
           set displayItem to emp1

      *    If one has say :
      *    set displayItem to objRef , where objRef was a class 
      *    which did not implement the Displayable interface,
      *    the Compiler will report a syntax error.
      *    produce a syntax error

      *    Object views work too.

      *    Since displayItem could hold any kind of class
      *    set emp2 to displayItem is a syntax error. You need to use
      *    the object view syntax.

           set emp2 to displayItem as Employee
           invoke emp2 "display" 

      * Micro Focus extension to determine class type at run time 

           if displayItem instance of Employee
               set emp1 to displayItem as Employee
           else
               display "Not employee"
           end-if

      * One can also use this syntax with interface names

           if emp1 instance of Displayable
               display "Class implements Displayable"
           end-if

      * P020. Add items to class created from parameterized class.
      * DLinkList has been created from a parameterized class and has
      * been compiled such that its "add" method can only accept object
      * references of classes that implement displayable.
      *
           set displayList to DLinkList::"new"
           invoke displayList "add" using by value emp1
           invoke displayList "add" using by value car1
           invoke displayList "add" using by value indPlace1
           invoke displayList "add" using by value car2

      * P025. Display items in class created from parameterized class.
      *    invoke displayList "add" using by value objRef will give a
      *    syntax error ensuring no object references of the wrong type
      *    get into the linked list.

           move listSize of displayList to noItems
           if noItems > 0
               set displayItem to displayList::"getfirst"
               invoke displayList "getfirst" returning displayItem
      * Object reference Displayable, invoke will invoke the correct
      * class, one of Car, Employee or IndPlacement. This is safe from
      * run-time errors because the Compiler checks that all the classes
      * provide a "Display" method
               invoke displayItem "display"
               perform until exit
                   set displayItem to displayList::"getnext"
                   if displayItem not = null
                       invoke displayItem "display"
                   else
                       exit perform
                   end-if
               end-perform
           end-if
           stop run
           .
