Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Parametrisierte Klassen und Interfaces

&pagelevel(4)&pagelevel

Eine parametrisierte Klasse ist eine Klasse mit einem oder mehreren formalen Parametern. Von einem formalen Parameter ist lediglich bekannt, ob es sich um eine Klasse oder ein Interface handelt. Darüber hinausgehende konkrete Eigenschaften der formalen Parameter bleiben offen.

Eine parametrisierte Klasse wird genutzt, indem im REPOSITORY Paragraf des Nutzerprogramms eine Klasse K als Expansion der parametrisierten Klasse P mit aktuellen Parametern spezifiziert wird: die formalen Parameter sind dann durch die Namen von konkreten Klassen bzw. Interfaces (die aktuellen Parameter) zu ersetzen, ebenso wie der Name der parametrisierten Klasse durch den der konkreten Expansion. Dadurch entsteht zu diesem Zeitpunkt aus P die neue konkrete Klasse K, die sich wie eine nicht-parametrisierte Klasse verhält und auch so behandelt wird.

Die eigentliche Übersetzung dieser neuen Klasse K mit den ersetzten Klassen- bzw. Interfacenamen erfolgt automatisch im Anschluss an die Übersetzung des Nutzers (siehe handbuch „COBOL2000 Benutzerhandbuch“ [1]).
In diesem Zusammenhang werden folgende Formulierungen gebraucht:

  • Die konkrete Klasse K expandiert die parametrisierte Klasse P.

  • Die parametrisierte Klasse P wird expandiert als konkrete Klasse K.

Der Vorgang der Parameterersetzung, der Übersetzung und die dabei entstehende Klasse wird als „Expansion der parametrisierten Klasse P“ bezeichnet.

Jede solche Expansion einer parametrisieren Klasse erzeugt eine eigenständige konkrete Klasse. Sie hat ihr eigenes Fabrikobjekt und ist unabhängig von anderen Expansionen der gleichen parametrisierten Klasse.
Innerhalb einer Ablaufeinheit müssen jedoch die Namen aller angesprochenen Klassen eindeutig sein: wird eine parametrisierte Klasse P in mehreren Programmen der Ablaufeinheit mit dem gleichen Namen K expandiert, sollten auch bei diesen Expansionen die aktuellen Parameter die gleichen sein.

Der Vorteil von parametrisierten Klassen gegenüber solchen, die die gleiche Leistung an Stelle von Parametrisierung mittels universeller Objektreferenzen erbringen, liegt darin, dass der Compiler bereits statisch ein einziges mal zur Übersetzungszeit Prüfungen vornehmen kann, die im anderen Fall erst dynamisch wiederholt zur Ablaufzeit erfolgen.

Die obigen Beschreibungen für parametrisierte Klassen gelten für parametrisierte Interfaces analog.

Beispiel 12-22

Folgendes Beispiel zeigt eine „first-in-first-out“-Liste zur Aufnahme von Objektreferenzen. Deren Klasse soll noch nicht weiter festgelegt sein und ist daher als Parameter definiert. Eine solche Liste nimmt beliebig viele Elemente auf, wobei das Element, welches zuerst in die Liste eingetragen wurde, beim Lesen auch als erstes wieder zurückgegeben und gleichzeitig aus der Liste entfernt wird.

Realisiert wird diese Liste mit Hilfe der beiden parametrisierten Klassen FIFO-LISTE und LIST-ELEMENT1. Die Klasse FIFO-LISTE beschreibt die Verwaltungsstruktur für die gesamte Liste. Als Parameter hat sie die Klasse der aufzunehmenden Objekte, sowie zusätzlich die Klasse der entsprechenden konkreten Expansion von LIST-ELEMENT1.

Die parametrisierte Klasse LIST-ELEMENT1 beschreibt ein einzelnes Element der Liste. Als Parameter hat sie die Klasse der Objekte, deren Referenz in so einem Listenelement gespeichert wird. LIST-ELEMENT1 fungiert als „Hilfsklasse“, die nach außen hin gar nicht gesondert auftritt. Sie wird nur innerhalb der FIFO-LISTE genutzt und sollte dort automatisch mit passenden Parametern erzeugt werden.

Das Verschachteln von parametrisierten Klassen ist jedoch vom COBOL-Standard 2002 nicht erlaubt. Der Anwender muss daher die nötigen Expansionen selber programmieren.

       >>IMP Compiler-Action UPDATE-REPOSITORY ON                          a)
       IDENTIFICATION DIVISION.
>>>    CLASS-ID.                LIST-ELEMENT1 INHERITS BASE USING PAR.     b)
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL NAMES.
           TERMINAL IS TTT.
       REPOSITORY.
           CLASS                PAR,                                       b)
           CLASS                BASE.

FFF    FACTORY.
       PROCEDURE DIVISION.
+++    METHOD-ID.               MAKE-NEW.                                  c)
       DATA DIVISION.
       LINKAGE SECTION.
       01 P USAGE OBJECT REFERENCE PAR.
       01 R USAGE OBJECT REFERENCE ACTIVE-CLASS.
       PROCEDURE DIVISION USING BY VALUE P RETURNING R.
       1.
           INVOKE SELF "NEW" RETURNING R. 
           INVOKE R "SET-CONTENT" USING P. 
           EXIT METHOD. 
       END METHOD              MAKE-NEW. 
       END FACTORY. 

OOO    OBJECT. 
       DATA DIVISION. 
       WORKING-STORAGE SECTION. 
       01 NXT  USAGE OBJECT REFERENCE LIST-ELEMENT1.                       d)
       01 CONT USAGE OBJECT REFERENCE PAR.                                 e)
       PROCEDURE DIVISION. 

+++    METHOD-ID.               SET-NEXT.                                  f)
       DATA DIVISION. 
       LINKAGE SECTION. 
       01 P USAGE OBJECT REFERENCE LIST-ELEMENT1. 
       PROCEDURE DIVISION USING P. 
       1. 
           SET NXT TO P. 
           EXIT METHOD. 
       END METHOD               SET-NEXT.

+++    METHOD-ID.               GET-NEXT.
       DATA DIVISION.
       LINKAGE SECTION.
       01 R USAGE OBJECT REFERENCE LIST-ELEMENT1.
       PROCEDURE DIVISION RETURNING R.
       1.
           SET R TO NXT.
           EXIT METHOD.
       END METHOD               GET-NEXT.

+++    METHOD-ID.               GET-CONTENT.
       DATA DIVISION.
       LINKAGE SECTION.
       01 P USAGE OBJECT REFERENCE PAR.
       PROCEDURE DIVISION RETURNING P.
       1.
           SET P TO CONT.
           EXIT METHOD.
       END METHOD               GET-CONTENT.

+++    METHOD-ID.               SET-CONTENT.
       DATA DIVISION.
       LINKAGE SECTION.
       01 P USAGE OBJECT REFERENCE PAR.
       PROCEDURE DIVISION USING BY VALUE P.
       1.
           SET CONT TO P.
           EXIT METHOD.
       END METHOD               SET-CONTENT.
       END OBJECT.
       END CLASS                LIST-ELEMENT1. 

Anmerkungen

a)

Die Expansionen dieser Klasse gehen in die Expansionen der parametrisierten Klasse FIFO-LIST als Parameter ein. Daher müssen die Repository-Daten der jeweiligen Expansion von LIST-ELEMENT1 zur Verfügung stehen. Dies wird durch die Angabe der Direktive sichergestellt (für die korrekte Zuweisung eines Repository hat jedoch der Anwender zu sorgen, siehe Handbuch „COBOL2000 Benutzerhandbuch“ [ 1]).

b)Parameter PAR ist der Name der Klasse, deren Objektreferenzen in der Liste gespeichert werden sollen.
c)

Die Methode MAKE-NEW erzeugt ein neues Listenelement und versorgt auch die darin zu speichernde Objektreferenz. In die Liste eingekettet wird das Listenelement-Objekt jedoch noch nicht - das ist Aufgabe der Listenklasse FIFO-LIST.

d)Die Listenelemente sind einfach „vorwärts“ über eine Objektreferenz auf das nächst folgende Element in der Liste verkettet.
e)Der Nutzinhalt eines Listenelements besteht aus einer Objektreferenz für Objekte der Klasse, die später als aktueller Parameter angegeben wird oder davon erbender Klassen.
f)Die anderen 4 Methoden stellen die elementaren Zugriffe zum Schreiben bzw. Lesen der beiden Daten eines Listenelements dar.
Die eigentlichen Listenzugriffe, d.h. die Methoden APPEND-ENTRY und REMOVE-ENTRY werden von FIFO-LIST bereitgestellt. Als zusätzlicher Informationsdienst fungiert die Methode LIST-LENGTH.


        IDENTIFICATION DIVISION.
>>>>    CLASS-ID.                 FIFO-LIST INHERITS BASE
                                            USING PAR-OBJ, PAR-ELEM.        a)
        ENVIRONMENT DIVISION.
        CONFIGURATION SECTION.
        SPECIAL NAMES.
            TERMINAL IS TTT.
        REPOSITORY.
            CLASS                PAR-OBJ,
            CLASS                PAR-ELEM,
            CLASS                BASE.

OOO     OBJECT.
        DATA DIVISION.
        WORKING-STORAGE SECTION.
        01 ELEM-COUNT PIC S9(8) COMP-5 VALUE 0.                             b)
        01 FST        USAGE OBJECT REFERENCE PAR-ELEM.                      c)
        01 LST        USAGE OBJECT REFERENCE PAR-ELEM.                      c)
        PROCEDURE DIVISION.

+++     METHOD-ID.                APPEND-ENTRY.                             d)
        DATA DIVISION. 
        LOCAL-STORAGE SECTION.
        01 W USAGE OBJECT REFERENCE PAR-ELEM. 
        LINKAGE SECTION. 
        01 P USAGE OBJECT REFERENCE PAR-OBJ.
        PROCEDURE DIVISION USING P. 
        1. 
            INVOKE PAR-ELEM "MAKE-NEW" USING P RETURNING W. 
            IF LST = NULL
            THEN                       *> MAKE VERY FIRST ENTRY IN LIST 
              SET FST, LST TO W
              MOVE 1 TO ELEM-COUNT
            ELSE                       *> APPEND ENTRY TO THE END OF LIST
              INVOKE LST "SET-NEXT" USING W 
              SET LST TO W 
              ADD 1 TO ELEM-COUNT 
            END IF.
            EXIT METHOD.
        END METHOD                APPEND-ENTRY. 

+++     METHOD-ID.                REMOVE-ENTRY.                            e)
        DATA DIVISION.
        LOCAL-STORAGE SECTION.
        01 W USAGE OBJECT REFERENCE PAR-ELEM. 
        LINKAGE SECTION. 
        01 R USAGE OBJECT REFERENCE PAR-OBJ. 
        PROCEDURE DIVISION RETURNING R. 
        1.
            IF FST = NULL
            THEN                       *> LIST IS EMPTY 
              SET R TO NULL
            ELSE                       *> DELETE 1st LIST-ELEM,MAKE SURE 
                                       *> THAT IT WILL BE GARBAGE COLLECTED 
              INVOKE FST "GET-CONTENT" RETURNING R 
              SUBTRACT 1 FROM ELEM-COUNT 
              SET W TO FST 
              INVOKE W "GET-NEXT" RETURNING FST
              INVOKE W "SET-NEXT" USING NULL 
            END IF. 
            EXIT METHOD. 
        END METHOD                REMOVE-ENTRY.

+++     METHOD-ID.                LIST-LENGTH. 
        DATA DIVISION. 
        LINKAGE SECTION. 
        01 R PIC S9(8) COMP-5. 
        PROCEDURE DIVISION RETURNING R. 
        1. 
            MOVE ELEM-COUNT TO R. 
            EXIT METHOD. 
        END METHOD                LIST-LENGTH. 
        END OBJECT.
        END CLASS                 FIFO-LIST. 

Anmerkungen

a)Parameter PAR-OBJ ist der Name der Klasse, deren Objektreferenzen (auch die von Unterklassen) in der Liste gespeichert werden sollen.
Parameter PAR-ELEM ist der Name der dazu passenden expandierten Hilfsklasse LIST-ELEMENT1.
b)Dieser Zähler dient lediglich dem zusätzlichen Informationsdienst LIST-LENGTH. Für die Listenzugriffe und die Leistungen ist er nicht notwendig.
c)Zur Verwaltung der FIFO-Liste ist es ausreichend, das erste (FST) und das letzte (LST) Element der Liste auffinden zu können.
d)Die Methode APPEND-ENTRY erzeugt selbst ein neues Listenelement mit der als Parameter übergebenen Objektreferenz als Inhalt. Dieses neue Element wird als letztes in die Liste eingekettet und die Verwaltungsdaten werden entsprechend angepasst.
e)Die Methode REMOVE-ENTRY entfernt das erste Element aus der Liste und gibt die dort gespeicherte Objektreferenz zurück. Hierfür wäre es ausreichend, nur die Verwaltungsdaten anzupassen - um jedoch die garbage collection zu erleichtern, wird die Verkettung zur Liste im entfernten Listenelement auf NULL gesetzt.
Der folgende Programmausschnitt zeigt exemplarisch eine mögliche Anwendung dieser beiden parametrisierten Klassen:

Klasse A und B sind beliebige konkrete Klassen; FIFOB ist eine konkrete Klasse für eine „first-in-first-out“-Liste von Objektreferenzen für Objekte der Klasse B (und deren Unterklassen), FIFOA1 und FIFOA2 sind konkrete Klassen für „first-in-first-out“-Listen von Objektreferenzen der Klasse A (und deren Unterklassen).

        IDENTIFICATION DIVISION.
>>>>    PROGRAM-ID.                N.
        ...
        REPOSITORY. 
             CLASS              A,
             CLASS              B,
             CLASS              FIFOA1 EXPANDS FIFO-LIST USING A ELEMA        a)
             CLASS              FIFOA2 EXPANDS FIFO-LIST USING A ELEMA        a)
             CLASS              FIFOB EXPANDS FIFO-LIST USING B ELEMB         b)
             CLASS              ELEMA EXPANDS LIST-ELEMENT1 USING A           c)
             CLASS              ELEMB EXPANDS LIST-ELEMENT1 USING B        b) c)
             CLASS              LIST-ELEMENT1
             CLASS              FIFO-LIST
        ... 
        WORKING-STORAGE SECTION.
        01 FLA1       USAGE OBJECT REFERENCE FIFOA1.
        01 FLA2       USAGE OBJECT REFERENCE FIFOA2.
        01 FLA3       USAGE OBJECT REFERENCE FIFOA2.
        01 FLB        USAGE OBJECT REFERENCE FIFOB.
        01 OB         USAGE OBJECT REFERENCE B.
        01 W          PIC X(10).
        ...
            INVOKE FIFOA1 "NEW" RETURNING FLA1.
            INVOKE FIFOA2 "NEW" RETURNING FLA2.                                d)
            INVOKE FIFOA2 "NEW" RETURNING FLA3.                                d)
            INVOKE FIFOB  "NEW" RETURNING FLAB.
        ...
            INVOKE FLB "APPEND-ENTRY" USING OB. ...
            INVOKE FLB "REMOVE-ENTRY" RETURNING OB.
            IF OB = NULL                                                       e)
              DISPLAY " ---> LISTE LEER"
            ELSE
              ...

Anmerkungen

a)Obwohl bei FIFOA1 und FIFOA2 die parametrisierte Klasse und die aktuellen Parameter identisch sind, entstehen aufgrund der unterschiedlichen Namen bei den beiden Expansionen zwei verschiedene konkrete Klassen.
b)

Es ist erlaubt, die Expansion einer parametrisierten Klasse (hier ELEMB) als aktuellen Parameter für eine andere Expansion (hier FIFOB) zu verwenden, solange dadurch keine zyklischen Abhängigkeiten entstehen. Es ist jedoch verboten, eine parametrisierte Klasse selbst, z.B. LIST-ELEMENT1, als aktuellen Parameter zu verwenden.
Der Compiler führt nachfolgende Expansionen nicht zwingend in der Reihenfolge aus, wie sie im Programm geschrieben wurden, sondern so, dass notwendige Daten zu aktuellen Parametern rechtzeitig vor der Expansion verfügbar sind.

c)Die Expansion der beiden Hilfsklassen ELEMA und ELEMB ist wegen den oben erwähnten Restriktionen des COBOL-Standards vom Anwender anzugeben. Diese Klassen zu verwenden, Objekte davon zu erzeugen usw. sollte allein den Expansionen von FIFO-LIST vorbehalten bleiben!
d)

Von der Expansion einer parametrisierten Klasse können mehrere konkrete Objekte erzeugt werden. Mittels der Objektreferenzen FLA2 und FLA3 stehen dem Programm hier 2 FIFO-Listen für Objekte der Klasse A zur Verfügung. Dieses Verfahren leistet das gleiche wie die in Anmerkung a) beschriebene Lösung - mittels 2 verschiedenen, aber leistungsmäßig identischen Klassen. Es ist aber einfacher und daher auf jeden Fall vorzuziehen.

e)Ist die Liste leer, gibt die Methode REMOVE-ENTRY als Objektreferenz NULL zurück.