Dynamischer Methodenaufruf (Teil 327)

Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Die Objektorientierung mit ABAP®: Vererbung, Dynamische Programmierung, GUI Controls (u.a. ALV im OO).
12 Beiträge • Seite 1 von 1
12 Beiträge Seite 1 von 1

Dynamischer Methodenaufruf (Teil 327)

Beitrag von Icke0801 (Specialist / 126 / 97 / 7 ) »
Hallo zusammen,

Ich habe hier etliche Methoden in verschiedenen, die den gleichen Aufbau haben. Das kann man ja sicherlich verkürzen, und wir sind ja faul 😊

Code: Alles auswählen.

  DATA(object_ref) = cl_abap_typedescr=>describe_by_object_ref( lo_object ).
  DATA(class_desc) = CAST cl_abap_classdescr( object_ref ).
  READ TABLE class_desc->methods ASSIGNING FIELD-SYMBOL(<method>)
                                 WITH KEY name = 'GET_MACHWAS'.
  IF sy-subrc = 0.
    CALL METHOD lo_object->(<method>-name)
      RECEIVING
        result = result.
  ELSE.
    BREAK-POINT.
  ENDIF.
Dazu habe ich folgende Fragen:
  • wie komme ich an den Typen des Returning-Parameters (Inline Deklaration funktioniert hier nicht)
  • Warum kann ich nicht auf die Interface Methoden ('ZIF_INTERFACE~GET_MACHWAS') zugreifen?
    Der Read Table geht nur mit 'GET_MACHWAS'
Hat da jemand ein paar Tipps für mich?
--
Grüße aus der Endlosschleife
-= Icke =-
abapTools

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von a-dead-trousers (Top Expert / 4372 / 222 / 1175 ) »
Genau hierfür gibt es die Interfaces.

Code: Alles auswählen.

case type of lo_object.
  when type ZIF_INTERFACE into data(lr_interface).
    result = lr_interface->get_machwas( ).
  when others.
    BREAK-POINT.
endcase.
Sofern du deine Methoden damit verwaltest, kannst du beliebige Objekte verwenden und hast dennoch immer Zugriff darauf ohne auf RTTI oder andere dynamische Ansätze zurückzugreifen.

Der Ansatz mit CASE TYPE OF gefällt mir insofern am besten, als man damit in der 7.50er Syntax gleich mit Inline-Deklarationen eine Variable erzeugen kann und man muss sich nicht um die mögliche Exception bei einem gewöhnlichen Casting ( ?= ) kümmern. Außerdem prüft das Konstrukt auch ob lo_object überhaupt existiert und somit fällt auch ein zusätzliches IF ... IS BOUND bzw. IF ... IS NOT INITIAL weg.

EDIT:
Was den Typen des Returning-Parameters angeht, kannst du diesen ja entweder im Interface oder im DDIC definieren und kannst somit global darauf zugreifen.

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Icke0801

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von Icke0801 (Specialist / 126 / 97 / 7 ) »
a-dead-trousers hat geschrieben:
30.04.2022 10:28

Sofern du deine Methoden damit verwaltest, kannst du beliebige Objekte verwenden und hast dennoch immer Zugriff darauf ohne auf RTTI oder andere dynamische Ansätze zurückzugreifen.

Der Ansatz mit CASE TYPE OF gefällt mir insofern am besten, als man damit in der 7.50er Syntax gleich mit Inline-Deklarationen eine Variable erzeugen kann und man muss sich nicht um die mögliche Exception bei einem gewöhnlichen Casting ( ?= ) kümmern. Außerdem prüft das Konstrukt auch ob lo_object überhaupt existiert und somit fällt auch ein zusätzliches IF ... IS BOUND bzw. IF ... IS NOT INITIAL weg.
Die Klassen haben über 20 Interfaces. Deswegen bin ich diesen Weg gegangen. Die Methoden unterscheiden sich vom Namen und den Typen des Returning Parameters.
a-dead-trousers hat geschrieben:
30.04.2022 10:28
EDIT:
Was den Typen des Returning-Parameters angeht, kannst du diesen ja entweder im Interface oder im DDIC definieren und kannst somit global darauf zugreifen.
Ich muss ja herausfinden, welcher Type gerade am Wickel ist. Im DDIC sind die natürlich hinterlegt. Über cl_abap_classdescr bekomme ich diese Info aber leider nicht.
--
Grüße aus der Endlosschleife
-= Icke =-
abapTools

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von a-dead-trousers (Top Expert / 4372 / 222 / 1175 ) »
Icke0801 hat geschrieben:
30.04.2022 12:15
Die Klassen haben über 20 Interfaces. Deswegen bin ich diesen Weg gegangen. Die Methoden unterscheiden sich vom Namen und den Typen des Returning Parameters.
Das ist dann eh perfekt für CASE TYPE OF.
Je nachdem welches Interface das Objekt implementiert hat, kannst du den statischen Methodenaufruf damit realisieren.

Implementieren eigentlich alle Klassen die ganzen 20 Interfaces oder kannst du die Objekte irgendwie "gruppieren"? Sprich alle mit Interface A haben kein Interface B usw.
Wenn zweiteres, dann musst du dir eigentlich nur überlegen wie du effizient die Methodenaufrufe zusammenfassen kannst um möglichst kleine CASE TYPE OF-Konstrukte zu haben.

z.B. Zwei Interfaces haben die Methode GET_NAME aber mit unterschiedliche Parametern. Du willst aber von beiden die Werte als String bekommen. Also erstellst du eine neue Methode für deine Datenabfrage die GET_NAME(_STRING) heißt, als Importing ein Objekt übernimmt und als Ausgabe einen String liefert. In der Methode gibt es ein CASE TYPE OF für die beiden Interfaces und jeweils die zusätzlich notwendige Konvertierung des Returning-Parameters in einen String. Jetzt kannst du dir noch überlegen, ob bei einem anderen übergebenen Objekt, das nicht eines der beiden Interfaces implementiert, ein Fehler ausgelöst werden soll oder einfach ein leerer String zurückgeliefert werden soll. Je nachdem was man damit erreichen möchte macht das eine oder das andere mehr Sinn.
Will man z.B. die Objekte für eine Listausgabe "serialisieren" macht ein Fehler keinen Sinn. Wenn nichts für GET_NAME da ist, soll auch nichts angezeigt werden und nicht die Ausgabe abgebrochen werden. Braucht man den Wert hingegen für die weitere Verabeitung ist eine Exception ein besserer Indikator für einen inkonsitenten Zustand als ein leerer String.

EDIT:
Der große Vorteil ist, wie schon erwähnt, dass man über diesen Weg die statisch Syntaxprüfung nicht verliert. Wann immer sich eines der beteiligten Objekte/Interfaces derart ändert, dass man damit nicht mehr wie gewohnt weiterarbeiten kann merkt man das schon beim Aktivieren (oder spätestens beim Transportieren). Im dynamischen Ansatz (via RTTI und Co.) merkt man den Fehler uU erst am Produktivsystem wenn der Benutzer auf ein Objekt zugreift, dass man in all der Hektik am Testsystem nicht berücksichtigt hat.

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Icke0801

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von ralf.wenzel (Top Expert / 3917 / 199 / 280 ) »
Icke0801 hat geschrieben:
30.04.2022 12:15
Die Klassen haben über 20 Interfaces. Deswegen bin ich diesen Weg gegangen. Die Methoden unterscheiden sich vom Namen und den Typen des Returning Parameters.
Du hast also eine Klasse mit n Interfaces und weißt nicht, aus welchem Interface du die Methode aufrufst? Das halte ich für einen grundsätzlichen Designfehler. Ein Interface beschreibt eine Eigenschaft einer Klasse bzw. des daraus resultierenden Objektes und der Kontext des Aufrufes muss zu eben dieser Eigenschaft passen. Wenn du das bedenkst, löst sich dein Problem von selbst.


Ralf

Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
Icke0801

Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von Icke0801 (Specialist / 126 / 97 / 7 ) »
ralf.wenzel hat geschrieben:
01.05.2022 15:17
Du hast also eine Klasse mit n Interfaces und weißt nicht, aus welchem Interface du die Methode aufrufst? Das halte ich für einen grundsätzlichen Designfehler.
Wer sagt denn sowas? Mein Problem siehe Link
--
Grüße aus der Endlosschleife
-= Icke =-
abapTools

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von msfox (Specialist / 362 / 56 / 74 ) »
Icke0801 hat geschrieben:
30.04.2022 08:28

Code: Alles auswählen.

  DATA(object_ref) = cl_abap_typedescr=>describe_by_object_ref( lo_object ).
  DATA(class_desc) = CAST cl_abap_classdescr( object_ref ).
  READ TABLE class_desc->methods ASSIGNING FIELD-SYMBOL(<method>)
                                 WITH KEY name = 'GET_MACHWAS'.
  IF sy-subrc = 0.
    CALL METHOD lo_object->(<method>-name)
      RECEIVING
        result = result.
  ELSE.
    BREAK-POINT.
  ENDIF.
Von welchem Typ ist denn lo_object?
Ist für GET_MACHWAS() vielleicht ein Alias definiert. Denn normalweise müsste du ja beim Ausführen der Methode auch das Interface angeben.
Denn CALL METHOD lo_object->(<method>-name) bzw. o_object->GET_MACHWAS() sollte ohne Angabe des Inferfaces nicht funktionieren, wenn dafür in der Klasse kein Alias definiert ist.
--
Trotzdem habe ich den Sinn nicht ganz verstanden.
Jede Methode trotz gleichem Namen in unterschiedlichen Interfaces macht ja etwas anderes. Du willst diese jetzt einfach dynamisch ausführen. Damit muss ja sichergestellt bleiben, dass, ob die Methode gleich heißt, auch immer die gleichen Parameter hat.
Weiterhin geht ja jeglicher Verwendungsnachweis verloren, wenn man so etwas dynamisch macht.

Folgende Benutzer bedankten sich beim Autor msfox für den Beitrag:
Icke0801


Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von msfox (Specialist / 362 / 56 / 74 ) »
Icke0801 hat geschrieben:
02.05.2022 06:12
ralf.wenzel hat geschrieben:
01.05.2022 15:17
Du hast also eine Klasse mit n Interfaces und weißt nicht, aus welchem Interface du die Methode aufrufst? Das halte ich für einen grundsätzlichen Designfehler.
Wer sagt denn sowas? Mein Problem siehe Link
Du sagst so etwas indirekt. Wenn du nur ein Interface mit genau dieser Methode hättest, würdest du diese auch "normal" ausführen.

Folgende Benutzer bedankten sich beim Autor msfox für den Beitrag:
Icke0801


Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von Icke0801 (Specialist / 126 / 97 / 7 ) »
msfox hat geschrieben:
02.05.2022 08:37
Du sagst so etwas indirekt. Wenn du nur ein Interface mit genau dieser Methode hättest, würdest du diese auch "normal" ausführen.
Das ist doch gar nicht mein Problem.
Es geht hier um:
Dazu habe ich folgende Fragen:
wie komme ich an den Typen des Returning-Parameters (Inline Deklaration funktioniert hier nicht)
Warum kann ich nicht auf die Interface Methoden ('ZIF_INTERFACE~GET_MACHWAS') zugreifen?
Der Read Table geht nur mit 'GET_MACHWAS'
--
Grüße aus der Endlosschleife
-= Icke =-
abapTools

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von black_adept (Top Expert / 4066 / 120 / 934 ) »
Moin Icke,

so ganz schlau werde ich aus deiner Frage zwar auch nicht. Aber könnte es sein, dass du den FuBa SEO_PARAMETER_READ_ALL suchst?

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
Icke0801

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von a-dead-trousers (Top Expert / 4372 / 222 / 1175 ) »
Icke0801 hat geschrieben:
02.05.2022 11:34
Das ist doch gar nicht mein Problem.
Es geht hier um:
Dazu habe ich folgende Fragen:
wie komme ich an den Typen des Returning-Parameters (Inline Deklaration funktioniert hier nicht)
Warum kann ich nicht auf die Interface Methoden ('ZIF_INTERFACE~GET_MACHWAS') zugreifen?
Der Read Table geht nur mit 'GET_MACHWAS'
Und Ralf, msfox sowie meine Wenigkeit versuchen dir verständlich zu machen, dass du einen völlig falschen Ansatz verfolgst.
Wenn du bereits alles in Interfaces organisiert hast, dann verwende doch diese Interfaces für den Methodenaufruf. Du kannst ja sowieso nicht eine "zentrale" Methode für die Abfrage bauen, wenn alle Methoden unterschiedliche Parameter haben. Um unter dieser Vorraussetzung "dynamisch" auf die Methoden zuzugreifen musst du erst wieder ein riesiges CASE-Statement, z.B. bezogen auf den Methodennamen oder ähnliches, verwalten, damit du auf die jeweiligen Daten korrekt zugreifen kannst. Also warum nicht gleich den ganzen dynamischen Ansatz weglassen und ein CASE TYPE OF mit direktem Bezug auf die Interfaces verwenden?

Anyway:
Die Klasse CL_ABAP_CLASSDESCR bietet auch eine Methode GET_METHOD_PARAMETER_TYPE mit der du dir den Datentyp des Returning-Parameters deiner Methode zurückliefern lassen kannst. Die Liste der Parameter ist Teil des Attributs METHODS in CL_ABAP_CLASSDESCR und der dynamische Aufruf mit LO_OBJECT->('ZIF_INTERFACE~GET_MACHWAS') ist syntaktisch korrekt. Wenn er trotzdem fehlschlägt dann musst du dir die Exception dazu anschauen. Das gleiche gilt übrigens auch für den READ TABLE, sprich, wenn dein aktuelles Objekt das Interface ZIF_INTERFACE tatsächlich implementiert, gibt es auch einen Eintrag mit 'ZIF_INTERFACE~GET_MACHWAS' in der Tabelle.

Edit:
Ach ja, weil sich der Parameter-Name ja auch noch ändern kann, wirst du die komplett dynamische Syntax von CALL METHOD mit PARAMETER-TABLE und EXCEPTION-TABLE brauchen. Nur so als Hinweis.

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Icke0801

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Dynamischer Methodenaufruf (Teil 327)

Beitrag von Icke0801 (Specialist / 126 / 97 / 7 ) »
Jetzt hab ich verstanden, worauf Ihr hinaus wollt. Danke für diese Erklärungen.
Die Parameter habe ich im Griff. Wie die Exceptions der Methoden dann abgefangen werden, muss ich noch herausfinden.
--
Grüße aus der Endlosschleife
-= Icke =-
abapTools

Seite 1 von 1

Vergleichbare Themen

2
Antw.
1924
Views
Dynamischer Methodenaufruf mit dynamischer Tabelle
von mark.thk » 12.12.2018 10:34 • Verfasst in ABAP Objects®
5
Antw.
4655
Views
Dynamischer Methodenaufruf mit dynamischer Tabelle
von Tommy Nightmare » 08.09.2017 13:23 • Verfasst in ABAP Objects®
4
Antw.
19867
Views
Dynamischer Methodenaufruf
von Cola » 20.08.2009 14:55 • Verfasst in ABAP Objects®
6
Antw.
3130
Views
Ist ein dynamischer Methodenaufruf möglich?
von Michael.Nett » 14.11.2005 15:21 • Verfasst in ABAP® Core
2
Antw.
2568
Views
Dynamischer Methodenaufruf: Methode nicht gefunden
von ralf.wenzel » 08.09.2014 18:20 • Verfasst in ABAP Objects®

Über diesen Beitrag


Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.