Erste Schritte
Grundlegende Methoden und Konzepte anwenden
Mit lokalen Klassen arbeiten
Daten aus der Datenbank lesen
Mit strukturierten Datenobjekten arbeiten
Mit komplexen internen Tabellen arbeiten
Datenbankänderungen mit Business Objects implementieren
Das ABAP-RESTful-Anwendungsprogrammiermodell beschreiben

Instanzen für eine Klasse anlegen

Objective

After completing this lesson, you will be able to instanzen einer ABAP-Klasse anlegen.

Anlegen von Instanzen

Sie arbeiten mit Attributen wie mit normalen Variablen desselben Typs. Außerhalb der Klasse reicht der Attributname jedoch nicht aus, um das Attribut eindeutig zu identifizieren. Um ein statisches Attribut außerhalb der Klasse zu adressieren, geben Sie zuerst den Klassennamen, dann den statischen Komponentenselektor (=>) und erst dann den Attributnamen ein. Der statische Komponentenselektor ist ein Doppelpfeil, der aus dem Gleichheits- und dem Größer-als-Zeichen besteht.

Hinweis

Vor oder nach dem Komponentenselektor sind keine Leerzeichen erlaubt.

Bei Instanzattributen ist die Situation noch komplizierter: Um auf eine Instanzkomponente zugreifen zu können, benötigen Sie eine Referenzvariable.

Eine Referenzvariable ist eine spezielle Variable, mit der Sie Objekte anlegen, adressieren und verwalten können. Eine Referenzvariable wird verwendet, um auf die Instanz einer Klasse im Programmspeicher zu zeigen. Sie deklarieren Referenzvariablen über die Anweisung DATA mit dem Zusatz TYPE REF TO gefolgt vom Namen einer Klasse.

Der Initialwert einer Referenzvariablen wird als NULL-Referenz bezeichnet, die Referenz zeigt nirgendwo hin.

Zum Anlegen einer neuen Instanz für eine Klasse verwenden Sie den Operator NEW. Im obigen Beispiel wird ein Ausdruck NEW #( ) auf der rechten Seite einer Wertzuweisung verwendet. Das Ergebnis des Ausdrucks ist die Speicheradresse der neu angelegten Instanz. Diese Referenz wird dann in der Referenzvariable auf der linken Seite der Zuweisung gespeichert.

Möglicherweise haben Sie bemerkt, dass der Name der Klasse, die instanziiert werden soll, nicht im Ausdruck angezeigt wird. Aufgrund des Ortes des Ausdrucks NEW #( ) weiß das System jedoch bereits, dass die Zielvariable „connection" vom Typ „REF TO lcl_connection" ist und daher eine Instanz der Klasse „lcl_connection" erzeugt werden muss. Das Rautenzeichen nach dem Operator NEW bedeutet: „Den Typ der Variable vor dem Gleichheitszeichen verwenden". In komplexeren Szenarien können Sie hier den Namen der Klasse anstelle des Rautenzeichens angeben.

Hinweis

Zwischen den Klammern muss mindestens ein Leerzeichen stehen.

Wenn Sie eine Klasse zum ersten Mal adressieren (dies könnte beim Zugriff auf eine statische Komponente oder beim Anlegen einer Instanz für die Klasse der Fall sein), lädt das Laufzeitsystem auch die Klassendefinition in den Programmspeicher. Diese Klassendefinition enthält alle statischen Attribute, die nur einmal in der Klasse vorhanden sind, anstatt einmal in jeder Instanz.

Statische Komponenten werden über den Klassennamen und den statischen Komponentenselektor adressiert. Dies funktioniert nicht für Instanzkomponenten, da Sie die Instanz angeben müssen, auf die Sie zugreifen möchten.

Um ein Instanzattribut außerhalb der Klasse zu adressieren, geben Sie zuerst die Referenzvariable, dann den Selektor für die Instanzkomponente (->) und erst dann den Attributnamen ein. Der Selektor für die Instanzkomponente ist ein Pfeil, der aus dem Gleichheits- und dem Größer-als-Zeichen besteht.

Notiz

Im Gegensatz zu vielen anderen Programmiersprachen verwendet ABAP unterschiedliche Zeichen für den Instanzkomponentenselektor und den statischen Komponentenselektor.

Eines der Hauptmerkmale der objektorientierten Programmierung ist die Tatsache, dass Sie mehrere Instanzen für dieselbe Klasse anlegen können. Jede Instanz wird an einer anderen Stelle im Programmspeicher erzeugt, und die Werte von Instanzattributen in einer Instanz sind unabhängig von den Werten in anderen Instanzen. Wie die Grafik veranschaulicht, teilen sich Instanzen derselben Klasse den Wert für die statischen Attribute.

Durch die Zuweisung einer Referenzvariablen zu einer anderen, kopiert das System die Adresse des Objekts, auf das die erste Variable zeigt, in die zweite Referenzvariable. Dadurch zeigen beide Referenzvariablen auf das gleiche Objekt.

Sie können mit derselben Referenzvariable mehrere Instanzen für eine Klasse anlegen. Jedes Mal, wenn Sie den Ausdruck NEW #( ) verwenden, legt das System eine neue Instanz für die Klasse an und hinterlegt die Adresse der neuen Instanz in der Referenzvariablen. Die Adresse der neuen Instanz überschreibt jedoch die Adresse der vorherigen Instanz.

Im Beispiel oben überschreibt die Adresse von „lcl_connection (2)" die Adresse von „lcl_connection (1)". Folglich gibt es im Programm keine Referenzvariable mehr, die auf „lcl_connection (1)" zeigt. Wenn dies für eine Instanz auftritt, kann sie nicht mehr aus dem Programm adressiert werden.

Um zu verhindern, dass der Programmspeicher mit Objekten gefüllt wird, die nicht mehr adressiert werden und zu einem Überlauf führen können, verfügt das Laufzeitsystem über die Komponente „Garbage Collector". Der Garbage Collector ist ein Programm, das regelmäßig nach Objekten sucht, auf die keine Referenzen mehr zeigen, und diese dann löscht. Wenn Sie bei einem Programm die letzte Referenz auf ein Objekt löschen, indem Sie es überschreiben oder die Anweisung CLEAR verwenden, löscht der Garbage Collector das Objekt bei seinem nächsten Lauf.

Notiz

Am Ende eines Programms, wenn alle Referenzvariablen freigegeben werden, löscht der Garbage Collector alle Instanzen, auf die diese zeigten. Sie selbst müssen sich keine Gedanken über das Ressourcenmanagement im Programm machen.

Anlegen von Instanzen für eine ABAP-Klasse

Instanzverwaltung in einer internen Tabelle

Wenn Sie die Objekte behalten möchten, können Sie die Referenzen in einer internen Tabelle hinterlegen. Diese Technik eignet sich, wenn Sie eine ganze Reihe von Objekten anlegen. Sie ermöglicht die Verwendung einer einzelnen Referenzvariable, um viele Objekte anzulegen. Obwohl die Referenzvariable mit der Adresse des nächsten Objekts überschrieben wird, sind die vorhandenen Objekte sicher, da die interne Tabelle eine Referenz auf sie enthält. Löschen Sie deshalb nie die „letzte" Referenz auf die Objekte.

Verwalten von Instanzen in einer internen Tabelle

Instanzen anlegen und verwalten

In dieser Übung legen Sie Instanzen Ihrer lokalen Klasse an und verwalten diese.

Vorlage:

  • /LRN/CL_S4D400_CLS_LOCAL_CLASS (globale Klasse)

Lösung:

  • /LRN/CL_S4D400_CLS_INSTANCES (globale Klasse)

Aufgabe 1: Vorlage kopieren (optional)

Kopieren Sie die Vorlageklasse. Wenn Sie die vorherige Übung abgeschlossen haben, können Sie diese Aufgabe überspringen und mit der Bearbeitung Ihrer Klasse ZCL_##_LOCAL_CLASS fortfahren.

Schritte

  1. Öffnen Sie den Quelltext der globalen Klasse /LRN/CL_S4D400_CLS_LOCAL_CLASS im ABAP Editor.

    1. Wählen Sie in der Eclipse-Symbolleiste Open ABAP Development Object. Drücken Sie alternativ Strg + Umschalt + A.

    2. Geben Sie als Suchzeichenfolge /LRN/CL_S4D400_CLS ein.

    3. Wählen Sie aus der Liste der Entwicklungsobjekte /LRN/CL_S4D400_CLS_LOCAL_CLASS aus, und wählen Sie dann OK.

  2. Verknüpfen Sie die View Project Explorer mit dem Editor.

    1. Suchen Sie in der Symbolleiste Project Explorer die Drucktaste Link with Editor. Wählen Sie die Drucktaste, falls diese noch nicht markiert ist. Dadurch sollte das Entwicklungsobjekt, das im Editor geöffnet ist, im Project Explorer hervorgehoben sein.

  3. Kopieren Sie die Klasse /LRN/CL_S4D400_CLS_LOCAL_CLASS in eine Klasse in Ihrem eigenen Paket (Namensvorschlag: ZCL_##_INSTANCES, wobei ## für Ihre Gruppennummer steht).

    1. Klicken Sie in der View Project Explorer mit der rechten Maustaste auf die Klasse /LRN/CL_S4D400_CLS_LOCAL_CLASS, um das Kontextmenü zu öffnen.

    2. Wählen Sie im Kontextmenü Duplicate ...

    3. Geben Sie den Namen Ihres Pakets in das Feld Package ein. Geben Sie im Feld Name den Namen ZCL_##_INSTANCES ein, wobei ## für Ihre Gruppennummer steht.

    4. Passen Sie die Beschreibung an, und wählen Sie Next.

    5. Bestätigen Sie den Transportauftrag, und wählen Sie Finish.

Aufgabe 2: Eine Instanz anlegen

Deklarieren Sie in der Methode main Ihrer globalen Klasse eine Referenzvariable, und legen Sie eine Instanz Ihrer lokalen Klasse an.

Schritte

  1. Deklarieren Sie in der Methode if_oo_adt_classrun~main Ihrer globalen Klasse eine Referenzvariable (Namensvorschlag: connection), und geben Sie sie mit Ihrer lokalen Klasse lcl_connection ein.

    1. Wechseln Sie zur Registerkarte ///Globale Klasse.

    2. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      1234567
      METHOD if_oo_adt_classrun~main. DATA connection TYPE REF TO lcl_connection. ENDMETHOD.
  2. Erzeugen Sie eine Instanz der Klasse und setzen Sie die Attribute carrier_id und connection_id (Vorschlagswerte: LH für Attribut carrier_id und 0400 für Attribut connection_id).

    1. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      12345678
      DATA connection TYPE REF TO lcl_connection. connection = new #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'.

      Hinweis

      Nachdem Sie den Komponentenselektor (->) typisiert haben, drücken Sie Strg + Leertaste, um die Attributnamen aus einer Vorschlagsliste auszuwählen.
  3. Aktivieren Sie die Klasse, und analysieren Sie mit dem Debugger Schritt für Schritt, was passiert.

    1. Drücken Sie Strg + F3, um die Klasse zu aktivieren.

    2. Doppelklicken Sie auf den linken Rand des Editors neben der Zeile connection = new #( )., um einen Breakpoint zu setzen.

    3. Drücken Sie F9, um die Klasse auszuführen.

    4. Doppelklicken Sie auf das Wort connection, um den Inhalt der Referenzvariablen connection anzuzeigen.

    5. Drücken Sie F5, um im Debugger einen Schritt weiter zu gehen. Prüfen Sie, ob sich der Wert von connection geändert hat.

    6. Expandieren Sie in der View Variables die Verzweigung connection, um die Initialattribute der Klasse anzuzeigen.

    7. Drücken Sie F5, um im Debugger einen Schritt weiter zu gehen. Prüfen Sie, ob sich der Wert von carrier_id geändert hat.

    8. Drücken Sie erneut F5. Prüfen Sie, ob sich der Wert von Connection_ID geändert hat.

Aufgabe 3: Mehrere Instanzen verwalten

Legen Sie weitere Instanzen Ihrer lokalen Klasse an, und speichern Sie die Referenzen auf diese Instanzen in einer internen Tabelle.

Schritte

  1. Deklarieren Sie in der Methode if_oo_adt_classrun~main( ) Ihrer globalen Klasse eine interne Tabelle mit dem Zeilentyp REF TO lcl_connection (Namensvorschlag: connections).

    1. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      123456789
      DATA connection TYPE REF TO lcl_connection. DATA connections TYPE TABLE OF REF TO lcl_connection. connection = new #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'.
  2. Hängen Sie nach dem Instanziieren der Klasse und dem Setzen der Attribute die Objektreferenz an die interne Tabelle an.

    1. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      123456789
      connection = NEW #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'. APPEND connection TO connections.
  3. Legen Sie zwei weitere Instanzen der Klasse lcl_connection an, setzen Sie deren Instanzattribute auf andere Werte als in der ersten Instanz, und hängen Sie die Referenzen auf die neuen Instanzen an die interne Tabelle connections an. Verwenden Sie für alle drei Instanzen dieselbe Referenzvariable connection.

    1. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      12345678910111213141516171819202122
      connection = NEW #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'. APPEND connection TO connections. connection = NEW #( ). connection->carrier_id = 'AA'. connection->connection_id = '0017'. APPEND connection TO connections. connection = NEW #( ). connection->carrier_id = 'SQ'. connection->connection_id = '0001'. APPEND connection TO connections.
  4. Aktivieren Sie die Klasse, und analysieren Sie mit dem Debugger Schritt für Schritt, was passiert.

    1. Drücken Sie Strg + F3, um die Klasse zu aktivieren.

    2. Doppelklicken Sie auf den linken Rand des Editors neben der ersten Zeile connection = new #( )., um den Breakpoint zu entfernen.

    3. Doppelklicken Sie auf den linken Rand des Editors neben der ersten Zeile APPEND connection TO connections., um einen neuen Breakpoint zu setzen.

    4. Drücken Sie F9, um die Klasse auszuführen.

    5. Doppelklicken Sie auf das Wort connection, um den Inhalt der Referenzvariablen connection anzuzeigen.

    6. Doppelklicken Sie auf das Wort connections, um den Inhalt der internen Tabelle connections anzuzeigen.

    7. Drücken Sie F5, um im Debugger einen Schritt weiter zu gehen. Prüfen Sie, ob sich der Inhalt von connections geändert hat.

    8. Expandieren Sie in der View Variables die Verzweigung connections, um den Inhalt der internen Tabelle anzuzeigen.

    9. Drücken Sie mehrmals F5, bis Sie das Ende des Programms erreicht haben. Überprüfen Sie dabei den Inhalt der internen Tabelle.

    10. Vergleichen Sie Ihren Quelltext auf der Registerkarte ///Global Class mit dem folgenden Auszug aus der Musterlösung:

      Code Snippet
      123456789101112131415161718192021222324252627282930313233343536
      METHOD if_oo_adt_classrun~main. DATA connection TYPE REF TO lcl_connection. DATA connections TYPE TABLE OF REF TO lcl_connection. * First Instance ********************************************************************** connection = NEW #( ). connection->carrier_id = 'LH'. connection->connection_id = '0400'. APPEND connection TO connections. * Second Instance ********************************************************************** connection = NEW #( ). connection->carrier_id = 'AA'. connection->connection_id = '0017'. APPEND connection TO connections. * Third Instance ********************************************************************** connection = NEW #( ). connection->carrier_id = 'SQ'. connection->connection_id = '0001'. APPEND connection TO connections. ENDMETHOD.