[ABAP] OO: Vererbung, Methodenredefinition, Vererbungshierarchie

* Einfache Klasse für Demo von Vererbung von Oberklasse an Unterklasse
* Methodenredefinition, Vererbungshierarchie

* Oberklasse
CLASS lcl_auto DEFINITION.
  PUBLIC SECTION.
* Instanzkonstruktor
    METHODS:
      constructor
        IMPORTING
          i_name TYPE string.

* funktionale Instanzmethode, gibt Namen zurück
    METHODS:
      get_name
        RETURNING VALUE(rv_name) TYPE string.

* funktionale Instanzmethode, gibt Ergebnis zurück
    METHODS:
      get_type_and_name
        RETURNING VALUE(rv_type_name) TYPE string.

  PROTECTED SECTION.
* funktionale Instanzmethode, ist nur innerhalb der Vererbungshierarchie sichtbar
    METHODS:
      get_type
        RETURNING VALUE(rv_type) TYPE string.

  PRIVATE SECTION.
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_auto IMPLEMENTATION.
  METHOD constructor.
    gv_name = i_name.
  ENDMETHOD.

  METHOD get_name.
    rv_name = gv_name.
  ENDMETHOD.

  METHOD get_type_and_name.
* Aufruf der verdeckten Klassen-Funktion über me-> (kann auch weggelassen werden)
    rv_type_name = |{ me->get_type( ) }: { gv_name }|.
  ENDMETHOD.

  METHOD get_type.
    rv_type = 'AUTO'.
  ENDMETHOD.
ENDCLASS.

* Unterklasse lcl_kombi, erbt von lcl_auto
CLASS lcl_kombi DEFINITION INHERITING FROM lcl_auto.
  PROTECTED SECTION.
* Methode der Oberklasse wird überschrieben
    METHODS:
      get_type REDEFINITION.
ENDCLASS.

CLASS lcl_kombi IMPLEMENTATION.
  METHOD get_type.
* Aufruf der Funktion der Oberklasse über "super"
    rv_type = |{ super->get_type( ) } -> KOMBI|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Kombi erzeugen
  DATA(o_kombi) = NEW lcl_kombi( 'Audi A3' ).
* Methode der Klasse lcl_auto auftrufen
  WRITE: / o_kombi->get_name( ).
* Methode der Klasse lcl_kombi auftrufen
  WRITE: / o_kombi->get_type_and_name( ).

[ABAP] OO: Vererbung, Polymorphie, Aggregation, CAST

* Einfache Klasse für Demo von Vererbung, Polymorphie und Casting (Up/Down) von Objektreferenzen

* Oberklasse
CLASS lcl_auto DEFINITION.
  PUBLIC SECTION.
    METHODS:
      constructor
        IMPORTING
          i_name TYPE string.

    METHODS:
      get_name
        RETURNING VALUE(rv_name) TYPE string.

  PRIVATE SECTION.
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_auto IMPLEMENTATION.
  METHOD constructor.
    gv_name = i_name.
  ENDMETHOD.

  METHOD get_name.
    rv_name = gv_name.
  ENDMETHOD.
ENDCLASS.

* Unterklasse, erbt von lcl_auto
CLASS lcl_kombi DEFINITION INHERITING FROM lcl_auto.
  PUBLIC SECTION.
    METHODS:
* neue funktionale Methode
* gibt Stauraum des Kombis zurück
      get_space
        RETURNING VALUE(rv_room) TYPE i.
ENDCLASS.

CLASS lcl_kombi IMPLEMENTATION.
  METHOD get_space.
    rv_room = 3.
  ENDMETHOD.
ENDCLASS.

* Unterklasse, erbt von lcl_auto
CLASS lcl_limo DEFINITION INHERITING FROM lcl_auto.
  PUBLIC SECTION.
    METHODS:
* neue funktionale Methode
* gibt cw-Wert zurück
      get_cw
        RETURNING VALUE(rv_cw) TYPE f.
ENDCLASS.

CLASS lcl_limo IMPLEMENTATION.
  METHOD get_cw.
    rv_cw = '1.22'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Aggregation: iTab mit Referenzen auf Autos
  DATA: it_cars TYPE STANDARD TABLE OF REF TO lcl_auto.

* verschiedene Autotypen erzeugen und in iTab ablegen
* impliziter Up-Cast (Widening-Cast) von lcl_kombi und lcl_limo -> lcl_auto
  APPEND NEW lcl_kombi( 'Audi A3' ) TO it_cars.
  APPEND NEW lcl_kombi( 'VW Passat' ) TO it_cars.
  APPEND NEW lcl_limo( 'Mercedes C' ) TO it_cars.
  APPEND NEW lcl_limo( 'Skoda Octavia' ) TO it_cars.

* Tabelle mit Autos durchgehen
  LOOP AT it_cars ASSIGNING FIELD-SYMBOL(<fs_car>).

* funktionale Methode von lcl_car aufrufen
    WRITE: / <fs_car>->get_name( ).

* spezielle Methoden der von lcl_auto abgeleiteten Unterklassen aufrufen
    TRY.
* probieren, ob sich das Auto zu einem Kombi casten lässt
* expliziter Down-Cast (Narrowing-Cast) von lcl_auto -> lcl_kombi
        DATA(o_kombi) = CAST lcl_kombi( <fs_car> ).
* Stauraum des Kombis ausgeben
        WRITE: / o_kombi->get_space( ), 'm³'.
      CATCH cx_sy_move_cast_error.
        WRITE: / 'Kein Kombi'.
    ENDTRY.

    TRY.
* probieren, ob sich das Auto zu einer Limo casten lässt
* expliziter Down-Cast (Narrowing-Cast) von lcl_auto -> lcl_limo
        DATA(o_limo) = CAST lcl_limo( <fs_car> ).
* cw-Wert der Limo ausgeben
        WRITE: / 'cw = ', o_limo->get_cw( ).
      CATCH cx_sy_move_cast_error.
        WRITE: / 'Keine Limo'.
    ENDTRY.

    ULINE.

  ENDLOOP.

[ABAP] OO: Implementation einer Factory-Klasse, Methodenverkettung (Method-Chaining)

* Einfache Klasse für Demo einer Factory-Klasse

* ist nicht über den Kontruktor von außen instanziierbar (CREATE PRIVATE), kann nur sich selbst instanziieren
* von lcl_factorydemo kann nicht geerbt werden (FINAL)
CLASS lcl_factorydemo DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
* statische Factory-Methode, übernimmt die Funktion des Konstruktors mit einigen organisatorischen Verbesserungen
    CLASS-METHODS:
      factory
        IMPORTING
                  i_object_name      TYPE string
        RETURNING VALUE(ro_instance) TYPE REF TO lcl_factorydemo.

* statische Methode, zeigt die interne sortierte Objektliste
    CLASS-METHODS:
      get_object_list.

* Instanzmethode, gibt Objektnamen
    METHODS:
      get_name
        RETURNING VALUE(rv_object_name) TYPE string.

  PRIVATE SECTION.
* eigener Listtyp zur Verwaltung der internen Objektreferenzen
* über "name" können die Objektreferenzen gesucht werden
    TYPES: BEGIN OF ty_instances,
             name       TYPE        string,
             o_instance TYPE REF TO lcl_factorydemo,
           END OF ty_instances.

* sortierte Liste zur Verwaltung der Objektreferenzen, Primärschlüssel ist "name"
    CLASS-DATA: git_instances TYPE SORTED TABLE OF ty_instances WITH UNIQUE KEY name.

* Instanzvariable, speichert Objektnamen
    DATA: gv_object_name TYPE string.

* versteckter Instanzkonstruktor, ist von außerhalb der Klasse nicht aufrufbar (CREATE PRIVATE)
    METHODS:
      constructor
        IMPORTING
          i_object_name TYPE string.
ENDCLASS.

CLASS lcl_factorydemo IMPLEMENTATION.
* versteckter Instanzkonstruktor, ist von außerhalb der Klasse nicht aufrufbar (CREATE PRIVATE)
  METHOD constructor.
    gv_object_name = i_object_name.
  ENDMETHOD.

* statische Factory-Methode
  METHOD factory.
    TRY.
* Instanz über den Namen suchen, wenn nicht vorhanden wird eine Exception CX_SY_ITAB_LINE_NOT_FOUND geworfen
        ro_instance = git_instances[ name = i_object_name ]-o_instance.
      CATCH cx_sy_itab_line_not_found.
* wenn also das Objekt nicht vorhanden ist, dann neues erzeugen
        ro_instance = NEW #( i_object_name ).
* und in die iTab eintragen, wird automatisch anhand des Namens einsortiert
        INSERT VALUE #( name = i_object_name
                        o_instance = ro_instance ) INTO TABLE git_instances.
    ENDTRY.
  ENDMETHOD.
* Instanzmethode, gibt Objektnamen
  METHOD get_name.
    rv_object_name = gv_object_name.
  ENDMETHOD.
* statische Methode, zeigt die interne sortierte Objektliste
  METHOD get_object_list.
    LOOP AT git_instances ASSIGNING FIELD-SYMBOL(<fs_inst>).
      WRITE: / <fs_inst>-name.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Drei Objekte per Factory-Methode erzeugen
* die ersten zwei Objekte werden erzeugt, da die Namen noch nicht
* in der internen Liste vorhanden sind
* die Objekte werden automatisch nach Namen sortiert (SORTED TABLE)
  DATA(o_ref1) = lcl_factorydemo=>factory( i_object_name = 'OBJ_2' ).
  WRITE: / o_ref1->get_name( ).

* Beispiel für Methodenverkettung (Method-Chaining)
  WRITE: / lcl_factorydemo=>factory( i_object_name = 'OBJ_1' )->get_name( ).

* das dritte Objekt wird nicht erzeugt, da schon ein Objekt mit dem gleichen Namen existiert
* daher wird nur die Referenz auf das namensgleiche Objekt zurückgegeben
  DATA(o_ref3) = lcl_factorydemo=>factory( i_object_name = 'OBJ_1' ).
  WRITE: / o_ref3->get_name( ).

  ULINE.

* sortierte Objektliste ausgeben -> nur zwei Objekte
* mit unterschiedlichen Namen werden angezeigt
  lcl_factorydemo=>get_object_list( ).

[ABAP] OO: Objektreferenzen in einer Liste verwalten, Objektsuche über Namen

* Demoklasse für Objekte, welche in einer sortierten Liste verwaltet werden
CLASS lcl_demo DEFINITION.
  PUBLIC SECTION.
    METHODS:
      constructor
        IMPORTING
          i_name TYPE string.

    METHODS:
      get_name
        RETURNING VALUE(rv_name) TYPE string.

  PRIVATE SECTION.
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_demo IMPLEMENTATION.
  METHOD constructor.
    gv_name = i_name.
  ENDMETHOD.

  METHOD get_name.
    rv_name = gv_name.
  ENDMETHOD.
ENDCLASS.

* Listtyp zur Verwaltung der internen Objektreferenzen
* über "name" können die Objektreferenzen gesucht werden
TYPES: BEGIN OF ty_instances,
         name       TYPE        string,
         o_instance TYPE REF TO lcl_demo,
       END OF ty_instances.

* sortierte Liste zur Verwaltung der Objektreferenzen, Primärschlüssel ist "name"
DATA: it_instances TYPE SORTED TABLE OF ty_instances WITH UNIQUE KEY name.

START-OF-SELECTION.
* Objekte generieren und in die iTab einfügen
* iTab wird automatisch anhand der Spalte "name" sortiert
  INSERT VALUE #( name = 'REF2'
                  o_instance = NEW #( 'Udo' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF1'
                  o_instance = NEW #( 'Heinz' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF4'
                  o_instance = NEW #( 'Horst' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF3'
                  o_instance = NEW #( 'Rainer' ) ) INTO TABLE it_instances.

* Objekt anhand eines Namens suchen
  DATA(o_ref) = it_instances[ name = 'REF1' ]-o_instance.
  WRITE: / o_ref->get_name( ).

* sortierte Objektliste ausgeben
  LOOP AT it_instances ASSIGNING FIELD-SYMBOL(<fs_inst>).
    WRITE: / <fs_inst>-name, <fs_inst>-o_instance->get_name( ).
  ENDLOOP.

[ABAP] OO: Interfacedefinition, Generalisierung, Spezialisierung

* Einfache Klassen für Demo für Verwendung von Interfaces
* Über Interfaces kann im ABAP Mehrfachvererbung (Polymorphie) realisiert werden

* Interface, dient als Schablone, ohne Implementierungen
INTERFACE lif_auto.
  METHODS:
* Interface-Methode, liefert Fahrtrichtung
    get_direction
      RETURNING VALUE(rv_direction) TYPE string.
ENDINTERFACE.

* Klasse Kombi, spezialisert das Interface lif_auto
CLASS lcl_kombi DEFINITION.
  PUBLIC SECTION.
* Implementiert das Interface lif_auto
    INTERFACES:
      lif_auto.

* ALias-Namen als Vereinfachung für Zugriff definieren
    ALIASES:
      get_direction FOR lif_auto~get_direction.

    METHODS:
      get_name
        RETURNING VALUE(rv_name) TYPE string.
ENDCLASS.

CLASS lcl_kombi IMPLEMENTATION.
* Implementierung der Interface-Methode, liefert Fahrtrichtung
  METHOD lif_auto~get_direction.
    rv_direction = 'Berlin'.
  ENDMETHOD.
* Instanzmethode, liefert Namen
  METHOD get_name.
    rv_name = 'Opel'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Objekt der Klasse Kombi + Funktionsaufruf
  DATA(o_ref) = NEW lcl_kombi( ).
* Aufruf der Instanzmethode
  WRITE: / 'Name:', o_ref->get_name( ).
* Aufruf der Interfacemethode allgemein
  WRITE: / 'Direction:', o_ref->lif_auto~get_direction( ).
* Aufruf der Interfacemethode über Alias-Namen (ALIASES)
  WRITE: / 'Direction:', o_ref->get_direction( ).

[ABAP] OO: Statischer Konstruktor, Instanzkonstruktor, statischer und dynamischer Methodenaufruf

* Einfache Klasse für Demo des statischen Konstruktors und des Instanzkonstruktors
* sowie eines statischen und dynamischen Methodenaufrufs
CLASS lcl_demo DEFINITION.
  PUBLIC SECTION.
* Instanzkonstruktor
    METHODS:
      constructor.

* funktionale Instanzmethode, gibt Ergebnis zurück
    METHODS:
      add
        IMPORTING
                  i_var1        TYPE i
                  i_var2        TYPE i
        RETURNING VALUE(rv_erg) TYPE i.

    CLASS-METHODS:
* statischer Konstruktor
      class_constructor.

* statische funktionale Methode, gibt Ergebnis zurück
    CLASS-METHODS:
      mul
        IMPORTING
                  i_var1        TYPE i
                  i_var2        TYPE i
        RETURNING VALUE(rv_erg) TYPE i.
ENDCLASS.

CLASS lcl_demo IMPLEMENTATION.
  METHOD class_constructor.
    WRITE: / 'statischer Konstruktor'.
  ENDMETHOD.

  METHOD constructor.
    WRITE: / 'dynamischer Konstruktor'.
  ENDMETHOD.

  METHOD add.
    rv_erg = i_var1 + i_var2.
  ENDMETHOD.

  METHOD mul.
    rv_erg = i_var1 * i_var2.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* erster Aufruf einer Methode der Klasse lcl_demo durch den Aufruf von mul( )
* -> ruft den Klassenkonstruktor, danach erst wird mul( ) statisch prozessiert
  WRITE: / lcl_demo=>mul( i_var1 = 4 i_var2 = 3 ).

* Objekt der Klasse lcl_demo erzeugen
  DATA(o_ref) = NEW lcl_demo( ).
* Methode add( ) aurufen
  WRITE: / o_ref->add( i_var1 = 2 i_var2 = 3 ).
* Methode mul( ) dynamisch prozessieren
  WRITE: / o_ref->mul( i_var1 = 2 i_var2 = 3 ).

[ABAP] OO: Instanzkonstruktor, funktionale Instanzmethode, Exceptionhandling

* Einfache Klasse für Demo des Konstruktors, Instanzmethode, Exceptionhandling
CLASS lcl_demo DEFINITION.
  PUBLIC SECTION.
* Instanzkonstruktor mit Übergabeparameter
* Propagiert Exception vom Typ cx_sy_create_object_error
    METHODS:
      constructor
        IMPORTING
          i_name TYPE string
        RAISING
          cx_sy_create_object_error.

* funktionale Instanzmethode, gibt Namen zurück
    METHODS:
      get_name RETURNING VALUE(rv_name) TYPE string.

  PRIVATE SECTION.
* globale, private Variable zur Speicherung des Namens
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_demo IMPLEMENTATION.
  METHOD constructor.
* prüfen, ob Name leer
    IF i_name = ''.
* Exception werfen
      RAISE EXCEPTION TYPE cx_sy_create_object_error.
    ELSE.
      gv_name = i_name.
    ENDIF.
  ENDMETHOD.

  METHOD get_name.
* Namen zurückgeben
    rv_name = gv_name.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Exception provozieren
  TRY.
      DATA(o_ref) = NEW lcl_demo( i_name = '' ).

      WRITE: / o_ref->get_name( ).

    CATCH cx_sy_create_object_error INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.
  
* "normale" Abarbeitung
  TRY.
      DATA(o_ref) = NEW lcl_demo( i_name = 'Test' ).

      WRITE: / o_ref->get_name( ).

    CATCH cx_sy_create_object_error INTO DATA(e_txt).
      WRITE: / e_txt->get_text( ).
  ENDTRY.

[ABAP] OO: Implementation einer Singleton-Klasse

* Singleton-Klasse, kann durch den Zusatz CREATE PRIVATE nur sich selbst instanziieren
* stellt einen Spezialfall einer Factory-Klasse dar
CLASS lcl_singleton DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
* Statischer Konstruktor, wird nur einmal aufgerufen
* erzeugt genau eine Referenz auf Singleton-Objekt
    CLASS-METHODS:
      class_constructor.

* Factory-Methode -> Gibt immer die gleiche Referenz auf Singleton-Objekt zurück
    CLASS-METHODS:
      get_instance RETURNING VALUE(ret_singleton) TYPE REF TO lcl_singleton.

* Testmethode, gibt eine GUID zurück
    METHODS:
      get_guid RETURNING VALUE(ret_guid) TYPE sysuuid_c32.

  PRIVATE SECTION.
* Referenz auf Singleton-Objekt
    CLASS-DATA: o_singleton TYPE REF TO lcl_singleton.
ENDCLASS.

CLASS lcl_singleton IMPLEMENTATION.
* Statischer Konstruktor, wird nur einmal aufgerufen
* erzeugt genau eine Referenz auf Singleton-Objekt
  METHOD class_constructor.
    o_singleton = NEW #( ).
  ENDMETHOD.

* Factory-Methode -> Gibt immer die gleiche Referenz auf Singleton-Objekt zurück
  METHOD get_instance.
    ret_singleton = o_singleton.
  ENDMETHOD.

* Testmethode, gibt eine GUID zurück
  METHOD get_guid.
    TRY.
        ret_guid = cl_system_uuid=>create_uuid_c32_static( ).
      CATCH cx_root.
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  DATA(o_ref) = lcl_singleton=>get_instance( ).

  WRITE: / |{ o_ref->get_guid( ) }|.

[ABAP] RANGES

Ein RANGE definiert eine spezielle interne Tabelle vom Typ STANDARD TABLE mit Header Line zur Abbildung von Intervallen (z.B. für SELECT-OPTIONS und WHERE … IN).
Die Definition von RANGES an sich ist obsolet.

Weiterführende Infos: Link und Link

Tabellenfelder einer RANGE-Tabelle

  • SIGN (Bereichabgrenzung)
    • Typ: DDSIGN
    • Domäne: DDSIGN
    • Werte
      • I Bereichsabgrenzung eingeschlossen (Inclusive)
      • E Bereichsabgrenzung ausgeschlossen (Exclusive)
  • OPTION (Optionen)
    • Typ: DDOPTION
    • Domäne: DDOPTION
    • Werte
      • EQ gleich
      • BT zwischen … und …
      • CP enthält das Template
      • LE kleiner oder gleich
      • GE größer oder gleich
      • NE ungleich
      • NB nicht zwischen … und …
      • NP enthält das Template nicht
      • GT größer
      • LT kleiner
  • LOW (niedrigster Wert des Intervalls)
    • Typ: C
    • Länge: 1…n (abh. vom Such-Datentyp)
  • HIGH (höchster Wert des Intervalls)
    • Typ: C
    • Länge: 1…n (abh. vom Such-Datentyp)
      (leer, wenn z.B. OPTION = EQ)

Beispiel 1 (Übergabe von RANGES (SELECT-OPTIONS) an Klassenmethoden)

REPORT zrange_demo.

* Klasse für Demo der Übergabe von RANGEs (SELECT-OPTIONS)
CLASS lcl_matnr DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      get_data
        IMPORTING
          i_it_matnr TYPE STANDARD TABLE. " RANGE (SELECT-OPTIONS) als STANDARD TABLE übergeben
ENDCLASS.

CLASS lcl_matnr IMPLEMENTATION.
  METHOD get_data.
    DATA: it_mara TYPE STANDARD TABLE OF mara WITH DEFAULT KEY.

* STANDARD TABLE im SQL verwenden
     SELECT * FROM mara INTO TABLE @it_mara
       WHERE matnr IN @i_it_matnr.

     ...

  ENDMETHOD.
ENDCLASS.

* SELECT-OPTIONS festlegen
DATA: lv_matnr TYPE mara-matnr.
* RANGE so_matnr für MATNR definieren
SELECT-OPTIONS: so_matnr FOR lv_matnr.

INITIALIZATION.
* RANGE so_matnr initialisieren
  so_matnr[] = VALUE #( ( sign   = 'I'
                          option = 'EQ'
                          low    = '0000012345'
                          high   = '' ) ).

START-OF-SELECTION.
* Datenbereich des RANGE so_matnr übergeben
  lcl_matnr=>get_data( i_it_matnr = so_matnr[] ).

Beispiel 2 (RANGE OF)

* erzeugt eine interne Tabelle vom Typ STANDARD TABLE mit Header Line mit den Datenfeldern
* SIGN (C(1)) | OPTION (C(2)) | LOW (C(10)) | HIGH (C(10))
DATA: it_kunnr TYPE RANGE OF kunnr.

Beispiel 3 (STANDARD TABLE)

TYPES: BEGIN OF ty_range,
         sign   TYPE ddsign,
         option TYPE ddoption,
         low    TYPE char18, " char18 für 18-stellige MATNR
         high   TYPE char18, " char18 für 18-stellige MATNR
       END OF ty_range.

* erzeugt eine interne Tabelle vom Typ STANDARD TABLE mit den Datenfeldern
* SIGN (C(1)) | OPTION (C(2)) | LOW (C(18)) | HIGH (C(18))
DATA: it_matnr TYPE STANDARD TABLE OF ty_range WITH DEFAULT KEY.

Beispiel 4 (STANDARD TABLE mit generischen DDIC-Strukturen)

DATA(rg_so_carrid) = VALUE rseloption( ( sign   = 'I'
                                         option = 'EQ'
                                         low    = 'AA'
                                         high   = '' ) ).

* DDIC-Zeilentypen, die RANGEs abbilden
* SELOPT
* RSDSSELOPT
* RSIS_S_RANGE

* DDIC-Tabellentypen, die RANGEs abbilden
* RSELOPTION
* CMS_TAB_BII_CAG_TYP_RNG
* FIWTIN_T_SELOPT
* PIQ_SELOPT_T
* PSI_WE_SELOPT_TT

[ABAP] OO: Events auslösen, Eventhandling

* Demo-Objekt, welches ein Event definiert und auslöst
CLASS lcl_demo DEFINITION.
  PUBLIC SECTION.
* der Event, der getriggert werden soll
    EVENTS:
      my_event
        EXPORTING
          VALUE(txt) TYPE string
          VALUE(val) TYPE i.

* Instanzkonstruktor mit Übergabeparameter
    METHODS:
      constructor
        IMPORTING
          iv_name TYPE string.

* die Methode, die den Event auslöst
    METHODS: write.

* gibt Namen zurück
    METHODS: get_name
      RETURNING VALUE(rv_name) TYPE string.

* Variable zum Speichern des Namens
  PRIVATE SECTION.
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_demo IMPLEMENTATION.
* Instanzkonstruktor mit Übergabeparameter
  METHOD constructor.
    gv_name = iv_name.
  ENDMETHOD.
* die Methode, die den Event auslöst
  METHOD write.
    WRITE: / '1. lcl_demo triggert Event "my_event"'.
* Event auslösen
    RAISE EVENT my_event
      EXPORTING
        txt = 'Übergabetext'
        val = 1.
  ENDMETHOD.
* gibt Namen zurück
  METHOD get_name.
    rv_name = gv_name.
  ENDMETHOD.
ENDCLASS.

* Eventhandlerklasse, die Methoden zur Ereignisbehalndlung abbildet
CLASS lcl_eventhandler DEFINITION.
  PUBLIC SECTION.
* die Ereignisbehandlungsroutine, die mit dem Event über SET HANDLER verknüpft wird
    CLASS-METHODS: on_my_event FOR EVENT my_event OF lcl_demo
      IMPORTING
          txt
          val
          sender.
ENDCLASS.

CLASS lcl_eventhandler IMPLEMENTATION.
* die Ereignisbehandlungsroutine, die mit dem Event verknüpft wird
  METHOD on_my_event.
    WRITE: / '2. lcl_eventhandler=>on_my_event:'.
    WRITE: / '   Name:', sender->get_name( ).
    WRITE: / '    txt:', txt.
    WRITE: / '    val:', val.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Objekt erzeugen
  DATA(o_evt) = NEW lcl_demo( 'Aufrufer-Objekt' ).

* Handler registrieren: Zuordnung von Eventhandler "on_my_event" zu Objekt der Demo-Klasse mit Eventtrigger für my_event
  SET HANDLER lcl_eventhandler=>on_my_event FOR o_evt.

* Funktionsaufruf, welcher den Event triggert
  o_evt->write( ).

Weiterführende Infos: Link und Link