This is a test message to test the length of the message box.
Login
ABAP Objekte prüfen (Instanzen)
Erstellt von Software-Heroes

ABAP - Objekte prüfen (Instanzen)

723

In diesem Artikel zeigen wir dir, wie du Instanzen analysieren und auf diese korrekt reagieren kannst, wenn du diese zum Beispiel bei einer Verarbeitung übergibst und individuell reagieren möchtest.

Werbung


Nicht immer kannst du davon ausgehen, dass deine Methodenschnittstelle korrekt versorgt wird, vor allem wenn du einen generischen Objekttypen zulässt. Für solche Fälle gibt es zwei neue Befehle, die dir das Arbeiten mit Instanzen etwas leichter machen sollen.

 

Klassenmodell

Für die heutigen Beispiele implementieren wir einige Klassen und Interfaces in Hierarchie, um so die Funktionsweise der beiden neuen Befehle zu demonstrieren. Dazu im ersten Schritt das Datenmodell, basierend auf der abstrakten Klasse LCL_VEHICLE und den entsprechend erbenden Klassen.

 

 

Die zweite Testreihe basiert auf einem Interface und den beiden implementierenden Klassen. Die Tiere implementieren das entsprechende Interface und die Methode.

 

 

Für die oben gezeigten Hierarchien hier noch die entsprechende minimale Definition in ABAP. Dabei verwenden wir zur Ausgabe das übergebene Objekt des Class Runners.

*** Class and interface definitions
CLASS lcl_vehicle DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS:
      speed_up
        IMPORTING
          io_output TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.

CLASS lcl_car DEFINITION INHERITING FROM lcl_vehicle.
  PUBLIC SECTION.
    METHODS:
      open_luggage_space
        IMPORTING
          io_output TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.

CLASS lcl_bwm DEFINITION INHERITING FROM lcl_car.
ENDCLASS.

CLASS lcl_truck DEFINITION INHERITING FROM lcl_vehicle.
  PUBLIC SECTION.
    METHODS:
      open_bedroom
        IMPORTING
          io_output TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.

CLASS lcl_man DEFINITION INHERITING FROM lcl_truck.
ENDCLASS.

CLASS lcl_plane DEFINITION INHERITING FROM lcl_vehicle.
ENDCLASS.

INTERFACE lif_animal.
  METHODS:
    make_sound
      IMPORTING
        io_output TYPE REF TO if_oo_adt_classrun_out.
ENDINTERFACE.

CLASS lcl_cat DEFINITION.
  PUBLIC SECTION.
    INTERFACES: lif_animal.
ENDCLASS.

CLASS lcl_dog DEFINITION.
  PUBLIC SECTION.
    INTERFACES: lif_animal.
ENDCLASS.


*** Implementations of the classes
CLASS lcl_car IMPLEMENTATION.
  METHOD open_luggage_space.
    io_output->write( 'I am opening the luggage space.' ).
  ENDMETHOD.
ENDCLASS.

CLASS lcl_truck IMPLEMENTATION.
  METHOD open_bedroom.
    io_output->write( 'I am opening the bedroom.' ).
  ENDMETHOD.
ENDCLASS.

CLASS lcl_cat IMPLEMENTATION.
  METHOD lif_animal~make_sound.
    io_output->write( 'Miou!' ).
  ENDMETHOD.
ENDCLASS.

CLASS lcl_dog IMPLEMENTATION.
  METHOD lif_animal~make_sound.
    io_output->write( 'Wuff!' ).
  ENDMETHOD.
ENDCLASS.

CLASS lcl_vehicle IMPLEMENTATION.
  METHOD speed_up.
    io_output->write( 'Over 9000!' ).
  ENDMETHOD.
ENDCLASS.

 

IS INSTANCE OF

Der Befehl prüft ein übergebenes Objekt (darf nicht Initial sein), ob es den Type einer Klasse oder eines Interfaces implementiert. Dies funktioniert auch über der Hierarchie der Objekte korrekt. Damit ist sichergestellt, dass die Methoden und Attribute der geprüften Klasse beim Objekt verfügbar sind. Du kannst den Befehl aber auch nutzen, um deine Fehlerbehandlung zu implementieren.

DATA(lo_bwm) = NEW lcl_bwm( ).

IF lo_bwm IS NOT INSTANCE OF lcl_vehicle.
  " Error handling
ENDIF.

 

Im oberen Beispiel haben wir eine Instanz der Klasse LCL_BWM erzeugt, dies kann genau so ein Übergabeparameter in eine Methode sein. Im nächsten Schritt wirde geprüft, ob das Objekt zur abstrakten Klasse LCL_VEHICLE gehört. Sollte dies nicht der Fall sein, kann eine entsprechende Fehlerbehandlung implementiert werden.

 

CASE TYPE OF

Bei diesem neuen Befehl handelt es sich um einen CASE mit einigen Besonderheiten und soweit für Instanzen optimiert. Hier kannst du eine Objektreferenz (nicht Initial) gegen verschiedene Typen (Klassen und Interfaces) prüfen und darauf reagieren. Dies eignet sich besonders gut, wenn du in einer Verarbeitung auf jedes beliebige Objekt reagieren möchtest. In diesem Fall stellen wir eine Methode zur Verfügung, die alle Arten von Objekten aufnehmen kann.

METHODS:
  react_for_different_objects
    IMPORTING
      io_object TYPE REF TO object
      io_output TYPE REF TO if_oo_adt_classrun_out
    RAISING
      cx_sy_conversion_unknown_unit.

 

Dieser Methode kannst du dann alle Arten von Objekten übergeben und diese Methode reagiert entsprechend auf den übergebenen Typ.

METHOD react_for_different_objects.
  CASE TYPE OF io_object.
    WHEN TYPE lif_animal INTO DATA(lo_animal).
      lo_animal->make_sound( io_output ).

    WHEN TYPE lcl_car INTO DATA(lo_car).
      lo_car->open_luggage_space( io_output ).

    WHEN TYPE lcl_truck INTO DATA(lo_truck).
      lo_truck->open_bedroom( io_output ).

    WHEN TYPE lcl_vehicle INTO DATA(lo_vehicle).
      lo_vehicle->speed_up( io_output ).

    WHEN OTHERS.
      RAISE EXCEPTION NEW cx_sy_conversion_unknown_unit( ).

  ENDCASE.
ENDMETHOD.

 

Mit dem Zusatz INTO erzeugst du eine Instanz vom Vergleichstyp im Hintergrund mit einem CAST. Damit hast du dann die Möglichkeit, direkt auf Attribute und Methoden zugrifen zu können (wie im Beispiel oben). Damit kann zum Beispiel eine weitere Verarbeitung angestoßen werden.

 

Beispiel

An dieser Stelle noch das vollständige Beispiel der Klasse mit der Main- und Testmethode. Die Ausgaben der Meldungen erfolgt über die Console in Eclipse.

CLASS zcl_bs_demo_instance DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      react_for_different_objects
        IMPORTING
          io_object TYPE REF TO object
          io_output TYPE REF TO if_oo_adt_classrun_out
        RAISING
          cx_sy_conversion_unknown_unit.
ENDCLASS.


CLASS zcl_bs_demo_instance IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA(lo_bwm) = NEW lcl_bwm( ).
    IF lo_bwm IS INSTANCE OF lcl_vehicle.
      out->write( 'LO_BMW is instance from object LCL_VEHICLE' ).
    ENDIF.

    DATA(lo_dog) = NEW lcl_dog( ).
    IF lo_dog IS INSTANCE OF lif_animal.
      out->write( 'LO_DOG is instance from interface LIF_ANIMAL' ).
    ENDIF.

    react_for_different_objects( io_output = out io_object = NEW lcl_car( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_truck( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_bwm( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_man( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_plane( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_dog( ) ).
    react_for_different_objects( io_output = out io_object = NEW lcl_cat( ) ).
  ENDMETHOD.


  METHOD react_for_different_objects.
    CASE TYPE OF io_object.
      WHEN TYPE lif_animal INTO DATA(lo_animal).
        lo_animal->make_sound( io_output ).

      WHEN TYPE lcl_car INTO DATA(lo_car).
        lo_car->open_luggage_space( io_output ).

      WHEN TYPE lcl_truck INTO DATA(lo_truck).
        lo_truck->open_bedroom( io_output ).

      WHEN TYPE lcl_vehicle INTO DATA(lo_vehicle).
        lo_vehicle->speed_up( io_output ).

      WHEN OTHERS.
        RAISE EXCEPTION NEW cx_sy_conversion_unknown_unit( ).

    ENDCASE.
  ENDMETHOD.
ENDCLASS.

 

Das erzeugte Ergebnis aus dem Lauf der Klasse sieht dann wie folgt aus. Die entsprechenden Zweige in der REACT Methode wurden durchlaufen:

 

Fazit

Ein Arbeiten mit generischen Objekten muss nicht immer schwer sein. Mit den beiden neuen Befehlen kannst du leicht das richtige Objekt herausfiltern und validieren und entsprechend darauf reagieren. In der Zukunft erhalten deine Programme etwas mehr Stabilität und Zuverlässigkeit.

 

Quellen:
SAP Dokumentation - IS INSTANCE OF
SAP Dokumentation - CASE TYPE OF


Enthaltene Themen:
Modernes ABAPInstanzenIS INSTANCE OFCASE TYPE OF
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


ABAP - Type Casting

Kategorie - ABAP

Wie kommst du eigentlich an den ursprünglichen Typ einer Klasse bzw. Instanz, wenn diese in einer generischen Tabelle übergeben wird? In diesem Artikel prüfen wir die Möglichkeiten.

16.04.2024

ABAP - RETURN value

Kategorie - ABAP

Nach all den Jahren ist nun endlich der "echte" Return in ABAP angekommen, in diesem Artikel zeigen wir dir, wie der funktioniert und was er kann.

13.02.2024

ABAP Deep Dive - FOR (Schleifen)

Kategorie - ABAP

Schauen wir uns einmal die FOR Schleife etwas näher an. Wie funktioniert sie? Was muss ich beachten und was kann ich damit tun?

14.04.2023

ABAP Deep Dive - Tabellenzugriff (intern)

Kategorie - ABAP

Schauen wir uns in diesem Artikel einmal den Tabellenzugriff auf interne Tabellen an und wie sie den READ TABLE ablösen.

03.02.2023

ABAP - FINAL

Kategorie - ABAP

In diesem Artikel schauen wir uns einmal das neue FINAL Sprachkonstrukt an, wie es funktioniert und was du damit anstellen kannst.

23.12.2022