Code: Alles auswählen.
CLASS zcl_fahrzeug DEFINITION PUBLIC ABSTRACT.
PUBLIC SECTION.
TYPES: BEGIN OF tys_fahrzeug,
hersteller TYPE string,
modell TYPE string,
kennzeichen TYPE string,
anzahl_sitze TYPE i,
END OF tys_fahrzeug,
tyt_fahrzeug TYPE SORTED TABLE OF tys_fahrzeug WITH UNIQUE KEY kennzeichen.
METHODS constructor IMPORTING
i_hersteller TYPE string
i_modell TYPE string
i_kennzeichen TYPE string.
METHODS get_fahrzeug RETURNING VALUE(rt_fahrzeug) TYPE tyt_fahrzeug.
PROTECTED SECTION.
PRIVATE SECTION.
DATA hersteller TYPE string.
DATA modell TYPE string.
DATA kennzeichen TYPE string.
ENDCLASS.
CLASS zcl_fahrzeug IMPLEMENTATION.
METHOD constructor.
hersteller = i_hersteller.
modell = i_modell.
kennzeichen = i_kennzeichen.
ENDMETHOD.
METHOD get_fahrzeug.
rt_fahrzeug = VALUE #( ( hersteller = hersteller kennzeichen = kennzeichen modell = modell ) ).
ENDMETHOD.
ENDCLASS.
Code: Alles auswählen.
CLASS zcl_pkw DEFINITION
PUBLIC
INHERITING FROM zcl_fahrzeug
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor IMPORTING
i_hersteller TYPE string
i_anzahl_sitze TYPE i
i_modell TYPE string
i_kennzeichen TYPE string.
METHODS get_fahrzeug REDEFINITION.
PROTECTED SECTION.
PRIVATE SECTION.
DATA anzahl_sitze TYPE i.
ENDCLASS.
CLASS zcl_pkw IMPLEMENTATION.
METHOD constructor.
super->constructor( i_hersteller = i_hersteller i_modell = i_modell i_kennzeichen = i_kennzeichen ).
anzahl_sitze = i_anzahl_sitze.
ENDMETHOD.
METHOD get_fahrzeug.
rt_fahrzeug = super->get_fahrzeug( ) .
rt_fahrzeug = VALUE #( BASE rt_fahrzeug ( anzahl_sitze = anzahl_sitze ) ).
ENDMETHOD.
ENDCLASS.
Code: Alles auswählen.
CLASS zcl_runclass DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_runclass IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA pkw TYPE ref to zcl_pkw.
pkw = new #( i_hersteller = 'BMW' i_kennzeichen = 'HD123' i_modell = 'I4' i_anzahl_sitze = 5 ).
out->write( pkw->get_fahrzeug( ) ).
ENDMETHOD.
ENDCLASS.
Code: Alles auswählen.
loop at lt_fahrzeug assigning field-symbol(<lr_fahrzeug>).
* (in ALV) Neue Zeile in Ausagabetabelle
* Die Spalten des Fahrzeugs verarbeiten.
case type of <lr_fahrzeug>.
when type zcl_pkw into data(lr_pkw).
* Die zusätzlichen Spalten des PKW verarbeiten.
when type zcl_lkw into data(lr_lkw).
* Die zusätzlichen Spalten des LKW verarbeiten.
when ...
...
endcase.
* (in write-Liste) Zeilenumbruch
endloop.
Code: Alles auswählen.
METHODS get_fahrzeug RETURNING VALUE(rt_fahrzeug) TYPE tys_fahrzeug.
Code: Alles auswählen.
CLASS zcl_fahrzeug DEFINITION ABSTRACT.
PUBLIC SECTION.
TYPES: BEGIN OF tys_fahrzeug,
hersteller TYPE string,
modell TYPE string,
kennzeichen TYPE string,
END OF tys_fahrzeug.
METHODS get_fahrzeug_data RETURNING VALUE(rs_fahrzeug) TYPE tys_fahrzeug.
METHODS constructor IMPORTING id_hersteller TYPE string
id_modell TYPE string
id_kennzeichen TYPE string.
PROTECTED SECTION.
PRIVATE SECTION.
DATA gs_fahrzeug TYPE tys_fahrzeug.
ENDCLASS.
CLASS zcl_fahrzeug IMPLEMENTATION.
METHOD constructor.
me->gs_fahrzeug-hersteller = id_hersteller.
me->gs_fahrzeug-modell = id_modell.
me->gs_fahrzeug-kennzeichen = id_kennzeichen.
ENDMETHOD.
METHOD get_fahrzeug_data.
rs_fahrzeug = me->gs_fahrzeug.
ENDMETHOD.
ENDCLASS.
CLASS zcl_pkw DEFINITION INHERITING FROM zcl_fahrzeug CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF tys_pkw,
anzahl_sitze TYPE i,
END OF tys_pkw.
TYPES BEGIN OF tys_fahrzeug_pkw.
INCLUDE TYPE tys_fahrzeug AS fahrzeug.
INCLUDE TYPE tys_pkw AS pkw.
TYPES END OF tys_fahrzeug_pkw.
METHODS constructor IMPORTING id_hersteller TYPE string
id_anzahl_sitze TYPE i
id_modell TYPE string
id_kennzeichen TYPE string.
METHODS get_pkw_data RETURNING VALUE(rs_pkw) TYPE tys_fahrzeug_pkw.
PROTECTED SECTION.
PRIVATE SECTION.
DATA gs_pkw TYPE tys_pkw.
ENDCLASS.
CLASS zcl_pkw IMPLEMENTATION.
METHOD constructor.
super->constructor( id_hersteller = id_hersteller
id_modell = id_modell
id_kennzeichen = id_kennzeichen ).
me->gs_pkw-anzahl_sitze = id_anzahl_sitze.
ENDMETHOD.
METHOD get_pkw_data.
rs_pkw-fahrzeug = me->get_fahrzeug_data( ).
rs_pkw-pkw = me->gs_pkw.
ENDMETHOD.
ENDCLASS.
In ABAP werden sehr oft Listausgaben verwendet und da benötigt man statische Strukturen (wenn man sich nicht mit dynamischen herumschlagen möchte). Da ist es dann oft einfacher "zusammengehörende" Attribute gleich als Struktur zu definieren um sie dann wiederverwenden zu können, so wie in dem konkreten Beispiel (oder am Besten gleich global im DDIC).Radinator hat geschrieben: ↑15.05.2025 13:05gibt es einen Grund warum es (in ABAP) sinnvoll ist die eigentlichen Instanzattribute, wie in diesem Beispiel etwa Hersteller und Co nicht, als einzelne Felder sondern als gesamter Typ zu machen?
Ich komm eigentlich aus der .NET Ecke und bin C# vorgeschädigt und mach ABAP nur wegen meiner Arbeit seit gut 5 Jahren. Für mich ist es etwas sinnlos das so zu machen da (hier der Vergleich zu C#) es doch viel umständlicher ist auf das Instanzobjekt zu greifen, davon die Getter Methode aufzurufen und dann auf das Resultat wieder zuzugreifen und dann erst das Attribute "in den Finger zu haben" anstelle direkt am InstanzObjekt auf das Attribut zugreifen zu können.
Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Radinator
Liste von Eigenschaften ... hmmm ... daran hatte ich gar nicht gedacht bzw. überlesen. 😞ralf.wenzel hat geschrieben: ↑16.05.2025 09:42Ich schrieb nicht von Listen von Fahrzeugen, sondern Listen von Eigenschaften in EINEM KONKRETEN Fahrzeug.
Du meinst also die Factory bestimmt, welche Eigenschaften(-objekte) die einzelnen Fahrzeuge erhalten? Also es gibt nur die ZCL_FAHRZEUG-Klasse und über die konkret zugewiesenen Eigenschaften ergibt sich ob es ein PKW oder LKW ist? Ja, ist natürlich auch möglich. Dann hat man aber eine relative intelligente Factory und löst damit eine "tiefe" Vererbung (ZCL_PKW, ZCL_LKW, etc. ) auf. Ich persönlich mag es aber lieber wenn ich Klassen auf einem Blick ansehe welche Funktion sie haben und nicht in einer Liste von Eigenschaften das raussuchen muss was mir zusagt. Deswegen arbeite ich auch immer stärker mit Interfaces wo ich mir per CAST die (Teil-)Informationen die ich brauche direkt aus dem Objekte rausholen kann. Vermutlich hab ich deswegen auch deinen Ansatz mit der Liste der Eigenschaften nicht sofort behirnt.ralf.wenzel hat geschrieben: ↑16.05.2025 09:42Ich schrieb auch nicht, dass die Oberklasse das machen sollte, sondern eine Factory-Klasse.
Danke 😇ralf.wenzel hat geschrieben: ↑16.05.2025 09:42Wenn ich dir nicht so wohlgesonnen wäre, wäre der erste Satz meiner Antwort gewesen „Liest du manchmal auch, was du kommentierst?“…
Das ist der Sinn einer Factory 😉 Dass dieser Entscheidungs- und Instanziierungs-Prozess zentralisiert, aber unabhängig vom Aufrufer UND den konkreten Klassen implementiert ist. Dann muss man die Aufrufer nicht anfassen und die konkreten Objekte auch nicht, wenn sich ein neues dazugesellt. Entweder die Ermittlung des konkreten Typs ist algorithmisch (dann muss man die Factory nichtmal anpassen) oder durch einen Case, dann muss man die Factory erweitern -- und natürlich die neue konkrete Klasse schreiben.a-dead-trousers hat geschrieben: ↑16.05.2025 10:40Du meinst also die Factory bestimmt, welche Eigenschaften(-objekte) die einzelnen Fahrzeuge erhalten? Also es gibt nur die ZCL_FAHRZEUG-Klasse und über die konkret zugewiesenen Eigenschaften ergibt sich ob es ein PKW oder LKW ist? Ja, ist natürlich auch möglich. Dann hat man aber eine relative intelligente Factory und löst damit eine "tiefe" Vererbung (ZCL_PKW, ZCL_LKW, etc. ) auf.