12. Nichtobjektorientierte Sprachen - PL/I

Dieses Kapitel soll nur ansatzweise zeigen, dass es durchaus möglich ist, auch in nichtobjektorientierten Sprachen einige Konzepte der OOP anzuwenden.

Realisierung von OO-Konzepten in PL/I:

Externe Prozedur für Klassendefinition (der PROC-Name und alle ENTRY-Namen dürfen höchstens 7 Stellen lang sein!):

PL/I-Klassendefinition allgemein
 /* beliebiger Kommentar (sollte eine Klassenbeschreibung beinhalten) */
 klanamK: PROC RETURNS (POINTER);

 /* Zeiger auf Instanz */
 DCL instanz POINTER;

 /* Deklaration der Klassenattribute */
 DCL klassattribut1  datentyp  STATIC  [ INIT(anfangswert) ];
 ...

 /* Deklaration einer BASED-Struktur mit allen Instanzattributen */
 DCL 1 klassenname_Attribute BASED(instanz),
       2 attribut1   datentyp,
       ... ;

 /* Deklaration der Parameter für alle Methoden */
 DCL this     POINTER;                 /* Zeiger auf Instanz (= this) (der Zeigername kann frei gewählt werden)         
	                                      Zugriff auf Instanzattribute:  this->attribut1  */
 DCL param11  datentyp;                /* Parameter für Methode1 */
 ...
 DCL param21  datentyp;                /* Parameter für Methode2 */
 ...

 /* Deklaration der lokalen Variablen für alle Methoden */
 DCL var11    datentyp;	               /* lokale Variable für Methode1 */
 ...
 DCL var21    datentyp;	               /* lokale Variable für Methode2 */
 ...

 /* Standardkonstruktor */
 ALLOCATE klassenname_Attribute;       /* Instanz erzeugen (durch Speicherplatzzuordnung) */
[ attribut1 = ... ; ]                  /* eventuell Attribute initialisieren */
 ...

 RETURN (instanz);                     /* Zeiger auf Instanz zurückgeben */

 /* weitere Konstruktoren */
 klanamK1: ENTRY (this, ... );
 this->attribut1 = ... ;               /* initialisieren Attribut1 */
 ...

 RETURN;

 ...

 /* Destruktor */
 klanamD: ENTRY (this);	
 instanz = this;
 FREE klassenname_Attribute;           /* Speicherplatz freigeben */
 RETURN;

 Gattribut1: ENTRY (this) RETURNS(datentyp);     /* Get-Methode für Attribut1 */
 RETURN (this->attribut1);

 Sattribut1: ENTRY (this, neuAttribut1);         /* Set-Methode für Attribut1 */
 this->attribut1 = neuAttribut1;
 RETURN;

 ...

 meth1: ENTRY (this [ , param11 ... ] );
 ...

 RETURN;

 meth2: ENTRY (this [ , param21 ... ] ) RETURNS (datentyp);
 ...

 RETURN (wert);

 ...

 Gklassattribut1: ENTRY RETURNS(datentyp);       /* Get-Methode für Klassenattribut1 */
 RETURN (klassattribut1);

 Sklassattribut1: ENTRY (neuKlassattribut1);     /* Set-Methode für Klassenattribut1 */
 klassattribut1 = neuKlassattribut1;
 RETURN;

 ...
 END klanamK;

Schnittstellendefinition = Deklaration aller Methoden (ENTRY-Deklarationen für externe Prozeduren):

PL/I-Schnittstellendefinition allgemein
 /* INCLUDE-DATEI klanamM */
 DCL klanam_NEW            GENERIC (klanamK  WHEN ());               /* Aliasname für Standardkonstruktor */
 DCL klanam_INIT           GENERIC (klanamK1 WHEN (*,*),             /* Aliasname für weitere Konstruktoren */
                                    klanamK2 WHEN (*,*,* ... ),      /*    (überladen der Konstruktoren)    */
                                     ...   );
 DCL klanam_DELETE         GENERIC (klanamD  WHEN (*));              /* Aliasname für Destruktor */

 DCL klanam_attribut1      GENERIC (Gattribut1 WHEN (*),             /* Aliasname f. Zugriffsmeth. (Instanzattribute) */
                                    Sattribut1 WHEN (*,*));
 ...

 DCL klanam_methode1       GENERIC (meth1 WHEN (* [ , * ... ] ));    /* Aliasname für Methode1 */
 DCL klanam_methode2       GENERIC (meth2 WHEN (* [ , * ... ] ));    /* Aliasname für Methode2 */
 ...

 DCL klanam_klassattribut1 GENERIC (Gklassattribut1 WHEN (),         /* Aliasname f. Zugriffsmeth. (Klassenattribute) */
                                    Sklassattribut1 WHEN (*));
 ...
 /* --------------------------------------------------------------------- */
 DCL klanamK         ENTRY    RETURNS (POINTER);                     /* Standardkonstruktor */
 DCL klanamK1        ENTRY (POINTER, datentyp);                      /* weitere Konstruktoren */
 DCL klanamK2        ENTRY (POINTER, datentyp, datentyp ... );
 ...
 DCL klanamD         ENTRY (POINTER);                                /* Destruktor */

 DCL Gattribut1      ENTRY (POINTER)    RETURNS(datentyp);
 DCL Sattribut1      ENTRY (POINTER, datentyp);
 ...

 DCL meth1           ENTRY (POINTER [ , datentypParam11 ... ] );
 DCL meth2           ENTRY (POINTER [ , datentypParam21 ... ] )    RETURNS (datentyp);
 ...

 DCL Gklassattribut1 ENTRY    RETURNS(datentyp);
 DCL Sklassattribut1 ENTRY (datentyp);
 ...

Bem.: Das GENERIC-Attribut dient zur Deklaration von Methodennamen mit mehr als 7 Zeichen, sowie zum Überladen von Methoden.

Hauptprogramm für Anwendung:

PL/I-Programm allgemein
 /* beliebiger Kommentar (sollte eine Programmbeschreibung beinhalten) */
 klanamP: PROC OPTIONS(MAIN);
 %INCLUDE PLICOPY(klanamM);            /* Einfügen der Schnittstellendefinition */                                      

 /* Zeiger auf Instanz */
 DCL instanz POINTER;	
 ...

 instanz = klanam_NEW();               /* Erzeugen der Instanz und ev. initialisieren */
[ CALL klanam_INIT(instanz , anfangswert1 [ , anfangswert1 ... ] ); ]
 ...

 CALL klanam_methode1(instanz [ , arg11 ... ] );
 ...

 x = klanam_methode2(instanz [ , arg21 ... ] );
 ...

 CALL klanam_DELETE(instanz);          /* Freigeben der Instanz */
 ...

 END klanamP;

Die nachfolgenden Beispiele entsprechen jenen aus Kap.2. Die Klassen- und Methodennamen wurden einfach auf 7 Stellen abgekürzt - ohne Rücksicht darauf, ob die so entstandenen externen Namen in einem Klassensystem eindeutig sein könnten. Weiters wird in den ersten Beispielen die Klasse als Klassenobjekt noch nicht als Attribut mitgeführt. Für die Vererbung und die Polymorphie (soweit diese eben ansatzweise realisierbar ist) wird dieses Attribut jedoch benötigt.

Zu den PL/I-Klassen:
Zaehler
Zaehler2
Person
Kunde
Zu den PL/I-Programmen:
ZaehlerProgramm
Zaehler2Programm
KundeProgramm


Externe Prozedur für Definition der Klasse Zaehler:

Klasse ZAEHLERK
*PROCESS AG A(FULL) F(I) GN MI('!') NEST S X INC;                               
 ZAEHLEK: PROC RETURNS (POINTER);

 /* ---------------------------------------------------------------
    ZEIGER AUF INSTANZ
    --------------------------------------------------------------- */

 DCL INSTANZ  POINTER;

 /* ---------------------------------------------------------------
    STRUKTUR FÜR INSTANZATTRIBUTE
    --------------------------------------------------------------- */

 DCL 1 ZAEHLER_ATTRIBUTE BASED(INSTANZ),
       2 WERT  BIN FIXED;

 /* ---------------------------------------------------------------
    PARAMETER FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL THIS        POINTER;            /* ZEIGER AUF INSTANZ (= THIS) */
 DCL NEUER_WERT  BIN FIXED;                     /* PAR. FÜR SETWERT */

 /* ---------------------------------------------------------------
    KONSTRUKTOREN UND DESTRUKTOR
    --------------------------------------------------------------- */

 /* STANDARDKONSTRUKTOR */
 ALLOCATE ZAEHLER_ATTRIBUTE;          /* SPEICHERPLATZZUORDNUNG FÜR
                                                   INSTANZATTRIBUTE */
 CALL RESET(INSTANZ);                             /* INITIALISIEREN */
 RETURN (INSTANZ);                /* ZEIGER AUF INSTANZ ZURÜCKGEBEN */

 /* DESTRUKTOR */
 ZAEHLED: ENTRY (THIS);
 INSTANZ = THIS;
 FREE ZAEHLER_ATTRIBUTE;                 /* SPEICHERPLATZ FREIGEBEN */
 RETURN;

 /* ---------------------------------------------------------------
    ZUGRIFFSMETHODEN (GET-/SET-METHODEN)
    --------------------------------------------------------------- */

 GETWERT: ENTRY (THIS) RETURNS (BIN FIXED);
 RETURN (THIS->WERT);

 SETWERT: ENTRY (THIS, NEUER_WERT);
 THIS->WERT = NEUER_WERT;
 RETURN;

 /* ---------------------------------------------------------------
    SONSTIGE INSTANZMETHODEN
    --------------------------------------------------------------- */

 ERHOEHE: ENTRY (THIS) RETURNS (BIN FIXED);
 CALL SETWERT(THIS, GETWERT(THIS)+1);
 RETURN (GETWERT(THIS));

 RESET: ENTRY (THIS);
 THIS->WERT = 0;
 RETURN;

 END ZAEHLEK;


Schnittstellendefinition (Deklaration aller Methoden zusammen mit ihren Aliasnamen):

Include-Datei ZAEHLERM
 /* ALIASNAME FÜR STANDARDKONSTRUKTOR */
 DCL ZAEHLER_NEW       GENERIC (ZAEHLEK WHEN ());                               
 /* ALIASNAME FÜR DESTRUKTOR  */
 DCL ZAEHLER_DELETE    GENERIC (ZAEHLED WHEN (*));

 /* ALIASNAMEN FÜR ZUGRIFFSMETHODEN */
 DCL ZAEHLER_WERT      GENERIC (GETWERT WHEN (*),
                                SETWERT WHEN (*,*));

 /* ALIASNAMEN FÜR SONSTIGE METHODEN */
 DCL ZAEHLER_ERHOEHEN  GENERIC (ERHOEHE WHEN (*));
 DCL ZAEHLER_RESET     GENERIC (RESET   WHEN (*));
 /* --------------------------------------------------------------- */
 DCL ZAEHLEK ENTRY   RETURNS (POINTER);
 DCL ZAEHLED ENTRY (POINTER);
 DCL GETWERT ENTRY (POINTER)   RETURNS (BIN FIXED);
 DCL SETWERT ENTRY (POINTER, BIN FIXED);
 DCL ERHOEHE ENTRY (POINTER)   RETURNS (BIN FIXED);
 DCL RESET   ENTRY (POINTER);


Hauptprogramm für Anwendung:

Hauptprogramm ZAEHLERP
*PROCESS AG A(FULL) F(I) GN MI('!') NEST S X INC;                               
 ZAEHLEP: PROC OPTIONS(MAIN);

 /* EINFÜGEN DER SCHNITTSTELLENDEFINITION */
 %INCLUDE ZAEHLERM;

 DCL Z  POINTER;                     /* ZEIGER AUF INSTANZ (= THIS) */
 DCL X  BIN FIXED;

 Z = ZAEHLER_NEW();                         /* ERZEUGEN DER INSTANZ */
 X = ZAEHLER_ERHOEHEN(Z);
 PUT SKIP LIST (ZAEHLER_WERT(Z));

 CALL ZAEHLER_DELETE(Z);                       /* INSTANZ FREIGEBEN */

 END ZAEHLEP;


Externe Prozedur für Definition der Klasse Zaehler2:

Klasse ZAEHLER2K
*PROCESS AG A(FULL) F(I) GN MI('!') NEST S X INC;                               
 ZAEHL2K: PROC RETURNS (POINTER);

 /* ---------------------------------------------------------------
    ZEIGER AUF INSTANZ
    --------------------------------------------------------------- */

 DCL INSTANZ  POINTER;

 /* ---------------------------------------------------------------
    KLASSENATTRIBUTE
    --------------------------------------------------------------- */

 DCL ENDWERT  BIN FIXED  STATIC  INIT(99);

 /* ---------------------------------------------------------------
    STRUKTUR FÜR INSTANZATTRIBUTE
    --------------------------------------------------------------- */

 DCL 1 ZAEHLER2_ATTRIBUTE BASED(INSTANZ),
       2 WERT  BIN FIXED;

 /* ---------------------------------------------------------------
    PARAMETER FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL THIS           POINTER;         /* ZEIGER AUF INSTANZ (= THIS) */
 DCL NEUER_WERT     BIN FIXED;                  /* PAR. FÜR SETWERT */
 DCL NEUER_ENDWERT  BIN FIXED;

 /* ---------------------------------------------------------------
    KONSTRUKTOREN UND DESTRUKTOR
    --------------------------------------------------------------- */

 /* STANDARDKONSTRUKTOR */
 ALLOCATE ZAEHLER2_ATTRIBUTE;         /* SPEICHERPLATZZUORDNUNG FÜR
                                                   INSTANZATTRIBUTE */
 CALL RESET(INSTANZ);                             /* INITIALISIEREN */
 RETURN (INSTANZ);                /* ZEIGER AUF INSTANZ ZURÜCKGEBEN */

 /* DESTRUKTOR */
 ZAEHL2D: ENTRY (THIS);
 INSTANZ = THIS;
 FREE ZAEHLER2_ATTRIBUTE;                /* SPEICHERPLATZ FREIGEBEN */
 RETURN;

 /* ---------------------------------------------------------------
    ZUGRIFFSMETHODEN (GET-/SET-METHODEN)
    --------------------------------------------------------------- */

 GETWERT: ENTRY (THIS) RETURNS (BIN FIXED);
 RETURN (THIS->WERT);

 SETWERT: ENTRY (THIS, NEUER_WERT);
 THIS->WERT = NEUER_WERT;
 IF (THIS->WERT > ENDWERT)
   THEN CALL RESET(THIS);
 RETURN;

 /* ---------------------------------------------------------------
    SONSTIGE INSTANZMETHODEN
    --------------------------------------------------------------- */

 ERHOEHE: ENTRY (THIS) RETURNS (BIN FIXED);
 CALL SETWERT(THIS, GETWERT(P)+1);
 RETURN (GETWERT(THIS));

 RESET: ENTRY (THIS);
 THIS->WERT = 0;
 RETURN;

 /* ---------------------------------------------------------------
    KLASSENMETHODEN
    --------------------------------------------------------------- */

 GETENDW: ENTRY RETURNS (BIN FIXED);
 RETURN (ENDWERT);

 SETENDW: ENTRY (NEUER_ENDWERT);
 ENDWERT = NEUER_ENDWERT;
 RETURN;

 END ZAEHL2K;


Schnittstellendefinition (Deklaration aller Methoden zusammen mit ihren Aliasnamen):

Include-Datei ZAEHLER2M
 /* ALIASNAME FÜR STANDARDKONSTRUKTOR */
 DCL ZAEHLER2_NEW      GENERIC (ZAEHL2K WHEN ());                               
 /* ALIASNAME FÜR DESTRUKTOR          */
 DCL ZAEHLER2_DELETE   GENERIC (ZAEHL2D WHEN (*));

 /* ALIASNAMEN FÜR ZUGRIFFSMETHODEN   */
 DCL ZAEHLER2_WERT     GENERIC (GETWERT WHEN (*),
                                SETWERT WHEN (*,*));

 /* ALIASNAMEN FÜR SONSTIGE METHODEN  */
 DCL ZAEHLER2_ERHOEHEN GENERIC (ERHOEHE WHEN (*));
 DCL ZAEHLER2_RESET    GENERIC (RESET   WHEN (*));
 /* --------------------------------------------------------------- */
 DCL ZAEHL2K ENTRY   RETURNS (POINTER);
 DCL ZAEHL2D ENTRY (POINTER);
 DCL GETWERT ENTRY (POINTER)   RETURNS (BIN FIXED);
 DCL SETWERT ENTRY (POINTER, BIN FIXED);
 DCL ERHOEHE ENTRY (POINTER)   RETURNS (BIN FIXED);
 DCL RESET   ENTRY (POINTER);


Hauptprogramm für Anwendung:

Hauptprogramm ZAEHLER2P
*PROCESS AG A(FULL) F(I) GN MI('!') NEST S X INC;                               
 ZAEHL2P: PROC OPTIONS(MAIN);

 /* EINFÜGEN DER SCHNITTSTELLENDEFINITION */
 %INCLUDE ZAEHLER2M;

 DCL Z          POINTER;             /* ZEIGER AUF INSTANZ (= THIS) */
 DCL (X, J, K)  BIN FIXED;

 Z = ZAEHLER2_NEW();                        /* ERZEUGEN DER INSTANZ */
 X = ZAEHLER2_ERHOEHEN(Z);
 DO K = 1 TO 3;
   DO I = 1 TO 80;
     X = ZAEHLER2_ERHOEHEN(Z);
   END;
   PUT SKIP LIST (ZAEHLER2_WERT(Z));
 END;

 CALL ZAEHLER2_DELETE(Z);                      /* INSTANZ FREIGEBEN */

 END ZAEHL2P;


Bei den nachfolgenden Beispielen aus Kap.4.4 wird auf folgende Art eine Eindeutigkeit der externen Namen erreicht:

kkkammm       kkk ... 3-stelliger systemweit eindeutiger Klassenname
        a ... Kennzeichen für Art der Methode:
        K ... Konstruktor
        D ... Destruktor
        G ... Get-Methode
        S ... Set-Methode
        B ... Berechnungen
        mmm ... 3-stelliger Methodenname (bei Zugriffsmethoden gekürzter Attributname)
kkkKLAS       Standardmethode für return des Attributs für den Klassennamen


Externe Prozedur für Definition der Klasse Person:

Klasse PERSONK
*PROCESS AG A(FULL) F(I) GS MI(']') NEST NC(E) OP S STG X INC;                  
 PERK: PROC RETURNS (POINTER);                                          
 /* JEDE INSTANZ DIESER KLASSE REPRÄSENTIERT EINE NATÜRLICHE PERSON */  
                                                                        
 /* ---------------------------------------------------------------
    ZEIGER AUF INSTANZ
    --------------------------------------------------------------- */

 DCL INSTANZ  POINTER;

 /* ---------------------------------------------------------------
    KLASSENATTRIBUTE
    --------------------------------------------------------------- */

 DCL MAENNLICH        CHAR (1)  STATIC  INIT('M');
 DCL WEIBLICH         CHAR (1)  STATIC  INIT('W');
 DCL ANREDEMAENNLICH  CHAR (18) STATIC  INIT('SEHR GEEHRTER HERR');     
 DCL ANREDEWEIBLICH   CHAR (18) STATIC  INIT('SEHR GEEHRTE FRAU ');     
                                                                        
 /* ---------------------------------------------------------------
    STRUKTUR FÜR INSTANZATTRIBUTE
    --------------------------------------------------------------- */

 DCL 1 PERSON_ATTRIBUTE BASED(INSTANZ),                                 
       2 NAME          CHAR (50)  VAR,                                  
       2 GEBDATUM      PIC '(8)9',                                      
       2 GESCHLECHT    CHAR (1),                                        
       2 ADRESSE       CHAR (100) VAR,                                  
       2 KLASSENOBJEKT CHAR (3);                                        
                                                                        
 /* ---------------------------------------------------------------
    PARAMETER FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL THIS            POINTER;        /* ZEIGER AUF INSTANZ (= THIS) */  
 DCL EINNAME         CHAR (50)  VAR;      /* PAR. FÜR KONSTRUKTOREN */  
 DCL EINDATUM        PIC '(8)9';    /* PAR. FÜR KONSTR. UND PERSGEB */  
 DCL KENNZGESCHLECHT CHAR (1);      /* PAR. FÜR KONSTR. UND PERSGES */  
 DCL EINEADRESSE     CHAR (100) VAR;      /* PAR. FÜR KONSTRUKTOREN */  
 DCL NEUERNAME       CHAR (50)  VAR;            /* PAR. FÜR PERSNAM */  
 DCL NEUEADRESSE     CHAR (100) VAR;            /* PAR. FÜR PERSADR */  
                                                                        
 /* ---------------------------------------------------------------
    LOKALE VARIABLE FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL DATETIME     BUILTIN;                                              
 DCL HEUTEDATUM   CHAR (17);                                            
 DCL HEUTE        PIC '(8)9'  DEFINED(HEUTEDATUM);                      
 DCL LFDJAHR      BIN FIXED;                                            
 DCL DIFF         BIN FIXED;                                            
                                                                        
 /* ---------------------------------------------------------------
    KONSTRUKTOREN UND DESTRUKTOR
    --------------------------------------------------------------- */

 /* STANDARDKONSTRUKTOR */                                              
 ALLOCATE PERSON_ATTRIBUTE;           /* SPEICHERPLATZZUORDNUNG FÜR 
                                                   INSTANZATTRIBUTE */
 KLASSENOBJEKT = 'PER';                                                 
 RETURN (INSTANZ);                /* ZEIGER AUF INSTANZ ZURÜCKGEBEN */  
                                                                        
 PERK1: ENTRY (THIS, EINNAME, EINDATUM, KENNZGESCHLECHT, EINEADRESSE);  
 CALL PERSNAM(THIS, EINNAME);
 CALL PERSGEB(THIS, EINDATUM;
 CALL PERSGES(THIS, KENNZGESCHLECHT);
 CALL PERSADR(THIS, EINEADRESSE;
 RETURN;                                                                
                                                                        
 PERK2: ENTRY (THIS, EINNAME, EINDATUM, KENNZGESCHLECHT);               
 CALL PERK1(THIS, EINNAME, EINDATUM, KENNZGESCHLECHT, 'LEER-P2');       
 RETURN;                                                                
                                                                        
 PERK3: ENTRY (THIS, EINNAME, KENNZGESCHLECHT);                         
 HEUTEDATUM = DATETIME;                                                 
 CALL PERK1(THIS, EINNAME, HEUTE, KENNZGESCHLECHT, 'LEER-P3');          
 RETURN;                                                                
                                                                        
 /* DESTRUKTOR */                                                       
 PERD: ENTRY (THIS);                                                    
 INSTANZ = THIS;                                                        
 FREE PERSON_ATTRIBUTE;                  /* SPEICHERPLATZ FREIGEBEN */  
 RETURN;                                                                
                                                                        
 /* ---------------------------------------------------------------
    ZUGRIFFSMETHODEN (GET-/SET-METHODEN)
    --------------------------------------------------------------- */

 PERGNAM: ENTRY (THIS) RETURNS (CHAR (50) VAR);                         
 RETURN (THIS->NAME);                                                   
                                                                        
 PERSNAM: ENTRY (THIS, NEUERNAME);                                      
 THIS->NAME = NEUERNAME;                                                
 RETURN;                                                                
                                                                        
 PERGGEB: ENTRY (THIS) RETURNS (PIC '(8)9');                            
 /* NUR EINE KOPIE DES ORIGINALOBJEKTS WIRD ZURÜCKGEGEBEN]          */  
 RETURN (THIS->GEBDATUM);                                               
                                                                        
 PERSGEB: ENTRY (THIS, EINDATUM);                                       
 THIS->GEBDATUM = EINDATUM;                                             
 RETURN;                                                                

 PERGGES: ENTRY (THIS) RETURNS (CHAR (1));                              
 RETURN (THIS->GESCHLECHT);                                             
                                                                        
 PERSGES: ENTRY (THIS, KENNZEICHEN);
 IF (KENNZEICHEN = MAENNLICH | KENNZEICHEN = WEIBLICH)
   THEN THIS->GESCHLECHT = KENNZEICHEN;
   ELSE PUT SKIP LIST ('UNGÜLTIGES KENNZEICHEN FÜR GESCHLECHT');        
 RETURN;                                                                
                                                                        
 PERGADR: ENTRY (THIS) RETURNS (CHAR (100) VAR);                        
 RETURN (THIS->ADRESSE);                                                
                                                                        
 PERSADR: ENTRY (THIS, NEUEADRESSE);                                    
 THIS->ADRESSE = NEUEADRESSE;                                           
 RETURN;                                                                
                                                                        
 /* ---------------------------------------------------------------
    SONSTIGE INSTANZMETHODEN
    --------------------------------------------------------------- */

 PERBANR: ENTRY (THIS) RETURNS (CHAR (18));                             
 IF (THIS->GESCHLECHT = MAENNLICH)                                      
   THEN RETURN (ANREDEMAENNLICH);                                       
   ELSE RETURN (ANREDEWEIBLICH);                                        
                                                                        
 PERBALT: ENTRY (THIS) RETURNS (BIN FIXED);                             
 HEUTEDATUM = DATETIME;                                                 
 LFDJAHR = HEUTE/10000;                                                 
 DIFF = THIS->GEBDATUM/10000;                                           
 DIFF = LFDJAHR - DIFF;                                                 
 RETURN (DIFF);                                                         
                                                                        
 /* ---------------------------------------------------------------
    STANDARDMETHODE FÜR RETURN DES ATTRIBUTS FÜR DEN KLASSENNAMEN
    --------------------------------------------------------------- */

 PERKLAS: ENTRY (THIS) RETURNS (CHAR (3));                              
 RETURN (THIS->KLASSENOBJEKT);                                          
                                                                        
 END PERK;                                                              
 


Deklaration der Struktur für die Instanzattribute (dient als LIKE-Struktur für abgeleitete Klassen):

Include-Datei PERSONA
 /* STRUKTUR MIT INSTANZATTRIBUTEN DER BASISKLASSE */                           
 DCL 1 PERSON_ATTRIBUTE,                                                
       2 NAME        CHAR(50)  VAR,                                     
       2 GEBDATUM    PIC'(8)9',                                         
       2 GESCHLECHT  CHAR(1),                                           
       2 ADRESSE     CHAR(100) VAR;                                     


Schnittstellendefinition (Deklaration aller Methoden zusammen mit ihren Aliasnamen):

Include-Datei PERSONM
 /* ALIASNAME FÜR STANDARDKONSTRUKTOR    */
 DCL PERSON_NEW           GENERIC (PERK    WHEN ());                            
 /* ALIASNAMEN FÜR WEITERE KONSTRUKTOREN */
 DCL PERSON_INIT          GENERIC (PERK1   WHEN (*,*,*,*,*),            
                                   PERK2   WHEN (*,*,*,*),              
                                   PERK3   WHEN (*,*,*));               
 /* ALIASNAME FÜR DESTRUKTOR             */
 DCL PERSON_DELETE        GENERIC (PERD    WHEN (*));                   
                                                                        
 /* ALIASNAMEN FÜR ZUGRIFFSMETHODEN      */
 DCL PERSON_NAME          GENERIC (PERGNAM WHEN (*),                    
                                   PERSNAM WHEN (*,*));                 
 DCL PERSON_GEBDATUM      GENERIC (PERGGEB WHEN (*),                    
                                   PERSGEB WHEN (*,*));                 
 DCL PERSON_GESCHLECHT    GENERIC (PERGGES WHEN (*),                    
                                   PERSGES WHEN (*,*));                 
 DCL PERSON_ADRESSE       GENERIC (PERGADR WHEN (*),                    
                                   PERSADR WHEN (*,*));                 

 /* ALIASNAMEN FÜR SONSTIGE METHODEN     */
 DCL PERSON_ANREDE        GENERIC (PERBANR WHEN (*));                   
 DCL PERSON_ALTER         GENERIC (PERBALT WHEN (*));                   
 DCL PERSON_KLASSENOBJEKT GENERIC (PERKLAS WHEN (*));                   
 /* --------------------------------------------------------------- */  
 DCL PERK    ENTRY   RETURNS (POINTER);                                 
 DCL PERK1   ENTRY (POINTER, CHAR(50)  VAR, PIC'(8)9', CHAR(1),         
                             CHAR(100) VAR);                            
 DCL PERK2   ENTRY (POINTER, CHAR(50)  VAR, PIC'(8)9', CHAR(1));        
 DCL PERK3   ENTRY (POINTER, CHAR(50)  VAR, CHAR(1));                   
 DCL PERD    ENTRY (POINTER);                                           
 DCL PERGNAM ENTRY (POINTER)   RETURNS (CHAR(50) VAR);                  
 DCL PERSNAM ENTRY (POINTER, CHAR(50) VAR);                             
 DCL PERGGEB ENTRY (POINTER)   RETURNS (PIC'(8)9');                     
 DCL PERSGEB ENTRY (POINTER, PIC'(8)9');                                
 DCL PERGGES ENTRY (POINTER)   RETURNS (CHAR(1));                       
 DCL PERSGES ENTRY (POINTER, CHAR(1));                                  
 DCL PERGADR ENTRY (POINTER)   RETURNS (CHAR(100) VAR);                 
 DCL PERSADR ENTRY (POINTER, CHAR(100) VAR);                            
 DCL PERBANR ENTRY (POINTER)   RETURNS (CHAR(18));                      
 DCL PERBALT ENTRY (POINTER)   RETURNS (BIN FIXED);                     
 DCL PERKLAS ENTRY (POINTER)   RETURNS (CHAR (3));                      


Externe Prozedur für Definition der Klasse Kunde:

Klasse KUNDEK
*PROCESS AG A(FULL) F(I) GS MI(']') NEST NC(E) OP S STG X INC;                  
 KUNK: PROC RETURNS (POINTER);
 /* INSTANZEN DIESER KLASSE REPRÄSENTIEREN KUNDEN */
 %INCLUDE PERSONM;                 /* EINFÜGEN METHODEN BASISKLASSE */
 %INCLUDE PERSONA;                /* EINFÜGEN ATTRIBUTE BASISKLASSE */

 /* ---------------------------------------------------------------
    ZEIGER AUF INSTANZ
    --------------------------------------------------------------- */

 DCL INSTANZ POINTER;

 /* ---------------------------------------------------------------
    STRUKTUR FÜR INSTANZATTRIBUTE
    --------------------------------------------------------------- */

 DCL 1 KUNDE_ATTRIBUTE BASED(INSTANZ),
       2 PERSON        LIKE PERSON_ATTRIBUTE,
       2 JAHRESUMSATZ  DEC FIXED (11,2),
       2 KREDITLIMIT   DEC FIXED (11,2),
       2 KLASSENOBJEKT CHAR (3);

 /* ---------------------------------------------------------------
    PARAMETER FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL THIS            POINTER;        /* ZEIGER AUF INSTANZ (= THIS) */  
 DCL EINNAME         CHAR (50)  VAR;      /* PAR. FÜR KONSTRUKTOREN */  
 DCL EINDATUM        PIC '(8)9';          /* PAR. FÜR KONSTRUKTOREN */  
 DCL KENNZGESCHLECHT CHAR (1);            /* PAR. FÜR KONSTRUKTOREN */  
 DCL EINEADRESSE     CHAR (100) VAR;      /* PAR. FÜR KONSTRUKTOREN */  
 DCL NEUERJAHRESUMSATZ DEC FIXED (11,2);        /* PAR. FÜR SETJUMS */  
 DCL NEUESKREDITLIMIT  DEC FIXED (11,2);        /* PAR. FÜR SETKLIM */  
                                                                        
 /* ---------------------------------------------------------------
    LOKALE VARIABLE FÜR ALLE METHODEN
    --------------------------------------------------------------- */

 DCL DATETIME     BUILTIN;                                              
 DCL HEUTEDATUM   CHAR (17);                                            
 DCL HEUTE        PIC '(8)9'  DEFINED(HEUTEDATUM);                      
 DCL LFDJAHR      BIN FIXED;                                            
 DCL JAHRE        BIN FIXED;                                            
                                                                        
 /* ---------------------------------------------------------------
    KONSTRUKTOREN UND DESTRUKTOR
    --------------------------------------------------------------- */

 /* STANDARDKONSTRUKTOR */
 ALLOCATE KUNDE_ATTRIBUTE;                                              
 JAHRESUMSATZ = 0;                                                      
 KREDITLIMIT = 0;                                                       
 KLASSENOBJEKT = 'KUN';                                                 
 RETURN (INSTANZ);                /* ZEIGER AUF INSTANZ ZURÜCKGEBEN */  
                                                                        
 KUNK1: ENTRY (THIS, EINNAME, EINDATUM, KENNZGESCHLECHT, EINEADRESSE);  
 CALL PERSON_INIT(THIS, EINNAME, EINDATUM, KENNZGESCHLECHT,             
                        EINEADRESSE);                                   
 RETURN;                                                                
                                                                        
 KUNK2: ENTRY (THIS, EINNAME, EINDATUM, KENNZGESCHLECHT);               
 CALL KUNK1(THIS, EINNAME, EINDATUM, KENNZGESCHLECHT, 'LEER-K2');       
 RETURN;                                                                
                                                                        
 KUNK3: ENTRY (THIS, EINNAME, KENNZGESCHLECHT);                         
 HEUTEDATUM = DATETIME;                                                 
 CALL KUNK1(THIS, EINNAME, HEUTE, KENNZGESCHLECHT, 'LEER-K3');          
 RETURN;                                                                
                                                                        
 /* DESTRUKTOR */                                                       
 KUND: ENTRY (THIS);                                                    
 INSTANZ = THIS;                                                        
 FREE KUNDE_ATTRIBUTE;                   /* SPEICHERPLATZ FREIGEBEN */   
 RETURN;                                                                
                                                                        
 /* ---------------------------------------------------------------
    ZUGRIFFSMETHODEN (GET-/SET-METHODEN)
    --------------------------------------------------------------- */

 KUNGJUM: ENTRY (THIS) RETURNS (DEC FIXED (11,2));                      
 RETURN (THIS->JAHRESUMSATZ);                                           
                                                                        
 KUNSJUM: ENTRY (THIS, NEUERJAHRESUMSATZ);                              
 THIS->JAHRESUMSATZ = NEUERJAHRESUMSATZ;                                
 RETURN;                                                                
                                                                        
 KUNGKLI: ENTRY (THIS) RETURNS (DEC FIXED (11,2));                      
 RETURN (THIS->KREDITLIMIT);                                            
                                                                        
 KUNSKLI: ENTRY (THIS, NEUESKREDITLIMIT);                               
 THIS->KREDITLIMIT = NEUESKREDITLIMIT;                                  
 RETURN;                                                                
                                                                        
 /* ---------------------------------------------------------------
    SONSTIGE INSTANZMETHODEN
    --------------------------------------------------------------- */

 KUNBALT: ENTRY (THIS) RETURNS (BIN FIXED);                             
 JAHRE = PERSON_ALTER(THIS);                                            
 RETURN (JAHRE + 500);                                                  
                                                                        
 /* ---------------------------------------------------------------
    STANDARDMETHODE FÜR RETURN DES ATTRIBUTS FÜR DEN KLASSENNAMEN
    --------------------------------------------------------------- */

 KUNKLAS: ENTRY (THIS) RETURNS (CHAR (3));                              
 RETURN (THIS->KLASSENOBJEKT);                                          
                                                                        
 END KUNK;                                                              


Schnittstellendefinition (Deklaration aller Methoden zusammen mit ihren Aliasnamen):

Include-Datei KUNDEM
 %INCLUDE PERSONM;

 /* ALIASNAME FÜR STANDARDKONSTRUKTOR    */
 DCL KUNDE_NEW           GENERIC (KUNK    WHEN ());                             
 /* ALIASNAMEN FÜR WEITERE KONSTRUKTOREN */
 DCL KUNDE_INIT          GENERIC (KUNK1   WHEN (*,*,*,*,*),             
                                  KUNK2   WHEN (*,*,*,*),               
                                  KUNK3   WHEN (*,*,*));                
 /* ALIASNAME FÜR DESTRUKTOR             */
 DCL KUNDE_DELETE        GENERIC (KUND    WHEN (*));                    
                                                                        
 /* ALIASNAMEN FÜR ZUGRIFFSMETHODEN      */
 DCL KUNDE_NAME          GENERIC (PERGNAM WHEN (*),                     
                                  PERSNAM WHEN (*,*));                  
 DCL KUNDE_GEBDATUM      GENERIC (PERGGEB WHEN (*),                     
                                  PERSGEB WHEN (*,*));                  
 DCL KUNDE_GESCHLECHT    GENERIC (PERGGES WHEN (*),                     
                                  PERSGES WHEN (*,*));                  
 DCL KUNDE_ADRESSE       GENERIC (PERGADR WHEN (*),                     
                                  PERSADR WHEN (*,*));                  
 DCL KUNDE_JAHRESUMSATZ  GENERIC (KUNGJUM WHEN (*),                     
                                  KUNSJUM WHEN (*,*));                  
 DCL KUNDE_KREDITLIMIT   GENERIC (KUNGKLI WHEN (*),                     
                                  KUNSKLI WHEN (*,*));                  
 /* ALIASNAMEN FÜR SONSTIGE METHODEN     */
 DCL KUNDE_ANREDE        GENERIC (PERBANR WHEN (*));                    
 DCL KUNDE_ALTER         GENERIC (KUNBALT WHEN (*));                    
 DCL KUNDE_KLASSENOBJEKT GENERIC (KUNKLAS WHEN (*));                    
 /* --------------------------------------------------------------- */  
 DCL KUNK    ENTRY   RETURNS (POINTER);                                 
 DCL KUNK1   ENTRY (POINTER, CHAR(50)  VAR, PIC'(8)9', CHAR(1),         
                             CHAR(100) VAR);                            
 DCL KUNK2   ENTRY (POINTER, CHAR(50)  VAR, PIC'(8)9', CHAR(1));        
 DCL KUNK3   ENTRY (POINTER, CHAR(50)  VAR, CHAR(1));                   
 DCL KUND    ENTRY (POINTER);                                           
 DCL KUNGJUM ENTRY (POINTER)   RETURNS (DEC FIXED (11,2));              
 DCL KUNSJUM ENTRY (POINTER, DEC FIXED (11,2));                         
 DCL KUNGKLI ENTRY (POINTER)   RETURNS (DEC FIXED (11,2));              
 DCL KUNSKLI ENTRY (POINTER, DEC FIXED (11,2));                         
 DCL KUNBALT ENTRY (POINTER)   RETURNS (BIN FIXED);                     
 DCL KUNKLAS ENTRY (POINTER)   RETURNS (CHAR (3));                      


Hauptprogramm für Anwendung:

Hauptprogramm KUNDEP
*PROCESS AG A(FULL) F(I) GS MI(']') NEST NC(E) OP S STG X INC;                  
 KUNDEP: PROC OPTIONS(MAIN);

 /* EINFÜGEN DER SCHNITTSTELLENDEFINITIONEN */
 %INCLUDE KUNDEM;                                              
 %INCLUDE PERSONM;                                              
                                                                        
 DCL (P1, K1, K2) POINTER;         /* ZEIGER AUF INSTANZEN (= THIS) */  
                                                                        
 /* ERZEUGEN DER INSTANZEN */  
 P1 = PERSON_NEW();
 CALL PERSON_INIT(P1, 'XXX', 19310217, 'W', 'ADRP1');                   
 K1 = KUNDE_NEW();                                                      
 CALL KUNDE_INIT(K1, 'HUGO H', 19670217, 'X', 'ADRK1');                 
 K2 = KUNDE_NEW();                                                      
 CALL KUNDE_INIT(K2, 'HUGO NUR 2', 'M');                                
                                                                        
 PUT SKIP LIST ('GESCHLECHT =' || PERSON_GESCHLECHT(P1) || '*');        
 PUT SKIP LIST ('GEBDATUM   =', PERSON_GEBDATUM(P1), '*');              
 PUT SKIP LIST ('ALTERP     =', PERSON_ALTER(P1), '*');                 
                                                                        
 PUT SKIP LIST ('GESCHLECHT =' || KUNDE_GESCHLECHT(K1) || '*');         
 PUT SKIP LIST ('GEBDATUM   =', KUNDE_GEBDATUM(K1), '*');               
 PUT SKIP LIST ('ALTERP     =', PERSON_ALTER(K1), '*');                 
 PUT SKIP LIST ('ALTERK     =', KUNDE_ALTER(K1), '*');                  
                                                                        
 PUT SKIP LIST ('GESCHLECHT =' || KUNDE_GESCHLECHT(K2) || '*');         
 PUT SKIP LIST ('GEBDATUM   =', KUNDE_GEBDATUM(K2), '*');               
 PUT SKIP LIST ('ALTERP     =', PERSON_ALTER(K2), '*');                 
 PUT SKIP LIST ('ALTERK     =', KUNDE_ALTER(K2), '*');                  
                                                                        
 CALL PERSON_DELETE(P1);                                                
 CALL KUNDE_DELETE(K1);                                                 
 CALL KUNDE_DELETE(K2);                                                 
                                                                        
 END KUNDEP;                                                            



Weiter
zu Kapitel 13 (Reservierte Worte)
Zurück
zum Anfang dieses Kapitels
zum Inhaltsverzeichnis
 
zu Kapitel 1
zu den Klassenbeispielen von Kapitel 2
zur Parameterübergabe (Kapitel 2.7.1)
zu Kapitel 3
zu den Klassenbeispielen von Kapitel 4
zu den Java-Klassenbeispielen von Kapitel 5.19.1 (Exceptions)
zu den Java-Klassenbeispielen von Kapitel 6 (Ein-/Ausgabe von Daten)
zu den Java-Klassenbeispielen von Kapitel 7 (GUI)
zu Kapitel 8 (JDBC)
zu den C#-Klassenbeispielen von Kapitel 9.19.1 (Exceptions)
zu den C#-Klassenbeispielen von Kapitel 10 (Ein-/Ausgabe von Daten)
Zur
Java-Dokumentation der Java-Beispiele