Code: Alles auswählen.
REPORT ZDKL_KLASSEN01.
class lcl_test DEFINITION.
public SECTION.
CLASS-METHODS:
ausgabe_test,
get_gebuehren_test
RETURNING VALUE(rv_gesamt_kosten) type zdklteilnehmer02.
endclass.
class lcl_test IMPLEMENTATION.
method ausgabe_test.
data ls_test type zdklteilnehmer02.
data lt_test type STANDARD TABLE OF zdklteilnehmer02.
data lv_gesamt_kosten type zdklteilnehmer02.
WRITE: / 'Namen', 'Kursnamen', 'Preis'.
ULINE.
SELECT * FROM zdklteilnehmer02 INTO ls_test where tname is NOT NULL and zzdklkurstitel is not null and tkurspreis is not null.
WRITE: / ls_test-tname , ls_test-zzdklkurstitel, ls_test-tkurspreis.
endselect.
lv_gesamt_kosten = get_gebuehren_test( ).
endmethod.
method get_gebuehren_test.
data lt_test type STANDARD TABLE OF zdklteilnehmer02.
data ls_test like line of lt_test.
data gesamt_kosten type i.
data gebuer type i.
gebuer = 100.
SKIP.
WRITE: / 'Gesamt Kosten'.
ULINE.
SELECT * FROM zdklteilnehmer02 INTO table lt_test where tkurspreis is not null and zzdklkurstitel is not null.
LOOP AT lt_test into ls_test.
IF ls_test-zzdklkurstitel = 'SAP-FINANZWESEN' or ls_test-zzdklkurstitel = 'NETZWERKTECHNIK' or ls_test-zzdklkurstitel = 'PC-GRUNDLAGEN'.
gesamt_kosten = ls_test-tkurspreis + gebuer.
MODIFY lt_test FROM ls_test.
ENDIF.
WRITE: / gesamt_kosten.
ENDLOOP.
gesamt_kosten = rv_gesamt_kosten.
endmethod.
endclass.
START-OF-SELECTION.
lcl_test=>ausgabe_test( ).
Code: Alles auswählen.
lv_gesamt_kosten = get_gebuehren_test( ).
Code: Alles auswählen.
gesamt_kosten = rv_gesamt_kosten.
Code: Alles auswählen.
rv_gesamt_kosten = gesamt_kosten.
stimmt... wobei es ja sein kann dass hier eventuell noch etwas dazukommt.msfox hat geschrieben:Macht keinen Sinn, weil danach die Methode zu ende ist.Code: Alles auswählen.
lv_gesamt_kosten = get_gebuehren_test( ).
Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag (Insgesamt 2):
tm987456 • Looper
Richtig schick wäre natürlich für alle DB-Zugriff eine eigene Klasse zu nehmen. Heißt dann DAO (Data Access Object) als Persistenzschicht.*ralf.wenzel hat geschrieben:Eine Methode für die DB-Zugriffe (READ....),
Jetzt kommt da aber nix, daher sollte die Zeile auch nicht enthalten sein....SaskuAc hat geschrieben:stimmt... wobei es ja sein kann dass hier eventuell noch etwas dazukommt.msfox hat geschrieben:Macht keinen Sinn, weil danach die Methode zu ende ist.Code: Alles auswählen.
lv_gesamt_kosten = get_gebuehren_test( ).
Genau sowas haben wir - eine Klasse pro DB-Zugriff und ideal zum Mocken. Die Persistenzschicht, die man sich generieren lassen kann, besteht aus Persistenzklassen. Die hab ich einmal ausprobiert, bin aber schnell an Grenzen gestoßen (kann man hier irgendwo nachlesen, sie lassen keine Klassenattribute zu). Auch bei Massenzugriffen ist das nicht ratsam, weil die Performance runtergeht.msfox hat geschrieben:Richtig schick wäre natürlich für alle DB-Zugriff eine eigene Klasse zu nehmen. Heißt dann DAO (Data Access Object) als Persistenzschicht.*ralf.wenzel hat geschrieben:Eine Methode für die DB-Zugriffe (READ....),
Hab ich mir angewöhnt. Hat den Vorteil, dass ich bei Unit-Tests einfach die Klasse austausche und die Test gegen Dummy-Daten laufen lassen kann.
*Ja man kann auch die Persistenzschicht generieren lassen, war mir aber zu verworren.
Letzteres ist zwar grundsätzlich zwar richtig, aber ich glaube, dass die Aufgabenstellung so gemeint war wie es bearbeitet wurde --> Thema bei weitem nicht verfehlt. Mit Übungsaufgaben kann man sich an OO langsam herantasten ohne gleich das ganze Thema verstanden haben zu müssen - darum geht es ja beim Lernen. Wenn man z.B. Deutsch als Fremdsprache lernen will fängt man ja auch nicht gleich mit Immanuel Kants "Kritik der reinen Vernunft" an sondern lernt erst mal ein paar grundsätzliche Vokabeln oder ein paar einfache Floskeln wie z.B. "Ich möchte diesen Teppich bitte nicht kaufen".ralf.wenzel hat geschrieben: Ich weiß, dass es nur eine Übungsaufgabe ist, aber das ist ein Aufsatz in der Schule auch, trotzdem schreibt man drunter "Thema verfehlt" wenn dem so ist.
und
Objektorientierung ist NICHT das Schreiben einer statischen Klasse, in der Methoden definiert sind, die dann prozedural abgearbeitet werden.
Die Aufgabenstellung war nicht eine instanziierbare Klasse zu schreiben. Davon abgesehen haben statische Methoden Vorteile gegenüber FORM-Routinen wegen ihres flexibleren Interfaces.ralf.wenzel hat geschrieben:Dann kannst du das auch einfach in einen Report schreiben.Eine statische Klasse bringt praktisch keine Vorteile.
@Ralf: Die Implikation "Eine Methode die den Wert eines Attributs zurückliefert sollte den Namen GET_... haben" unterschreibe ich dir gerne, aber die umgekehrte nicht. Den Grund hast du ja selber schon hinterher geschoben und im Gegensatz zu dir suche ich durchaus in den GET_ Methoden wenn ich eine Methode finden will, die mir etwas zurückliefern soll.Eine GET-Methode sollte den Wert eines Attributes zurückliefen. Eine Methode, die etwas anderes tut, sollte man nicht GET.... nennen. READ wäre deutlich sinniger gewählt.Eine Ausnahme kann man machen, wenn aus dem Namen ersichtlich wird, wenn KEIN Attributwert zurückgeliefert wird (GET_MATNR_FROM_BELEG), aber selbst davon würde ich abraten
Was Ralf hoffentlich sagen will ist:" Lange Codeblöcke sind unübersichtlich". Und das gilt nicht nur für Programmierung in Klassen sondern überall wo du Coding findest. Und Abhilf schafft man üblicherweise mit Modularisierung - egal ob nun mit Methoden, Funktionen, FORMs, MACROs oder was auch immer.ralf.wenzel hat geschrieben:Methoden sind sehr kurz.
Solche Verallgemeinerungen sind für Newbies nicht hilfreich. Zustimmung für bei der Aussage dass man für einen LOOP ein Feldsymbol verwenden sollte. Die Performance sollte allerdings bei der Wahl, ob man ein Feldsymbol, eine Referenz oder einen Arbeitsbereich verwendet ganz hinten in der Liste stehen. Aber ich gebe Ralf insofern recht, dass es im Allgemeinen wenig andere Gründe gibt, so dass die Performance als dann einziges Kriterium dann doch zur Verwendeung des Feldsymbols führt.ralf.wenzel hat geschrieben:Außerdem: Einen LOOP würde ich aus Performancegründen immer in ein Feldsymbol machen. SELECT/ENDSELECT-Schleifen sind auch Kappeskram. Besser wäre folgende Struktur:
Lob an Ralfralf.wenzel hat geschrieben:Verbesserungsvorschlag für den nächsten Versuch:
ff
Richtig, aber gerade für Methoden gilt die Regel "Jede Methode macht genau EINE Sache" (eine ähnliche Definition für FORM-Routinen ist mir nicht bekannt). Die gilt nicht nur oder speziell in ABAP, sondern grundsätzlich im OO.black_adept hat geschrieben:Was Ralf hoffentlich sagen will ist:" Lange Codeblöcke sind unübersichtlich". Und das gilt nicht nur für Programmierung in Klassen sondern überall wo du Coding findest. Und Abhilf schafft man üblicherweise mit Modularisierung - egal ob nun mit Methoden, Funktionen, FORMs, MACROs oder was auch immer.ralf.wenzel hat geschrieben:Methoden sind sehr kurz.
Da schreibt jemand, dass er seit zwei Wochen ABAP lernt, stellt eine gezielte Frage und liefert sogar seinen Quellcode dazu und du überrollst ihn mit Persistenzschichten, Feldsymbolen und was du alles in deinem Projekt machst...ralf.wenzel hat geschrieben:Also, da ist ja einiges schiefgelaufen.
Ralf
Folgende Benutzer bedankten sich beim Autor ewx für den Beitrag (Insgesamt 4):
DeathAndPain • deejey • Looper • Beat
ralf.wenzel hat geschrieben: Wenn du mir mal die Struktur deiner Tabelle ZDKLTEILNEHMER02 zeigst, kann ich dir mal ein Beispiel schreiben, wie ICH es machen würde.
Würde ich gerne mal sehen mit der hier schon oft erwähnten generischen Persistenzschicht. Also wenn dir am WE langweilig sein sollte...ralf.wenzel hat geschrieben: Bei uns ist es so, dass wir eine Klassenhierarchie haben - wir haben alles, was man generalisieren kann, in mehreren Schichten von Oberklassen stehe. Wie z. B. den SELECT. Das macht das Ganze etwas abstrakt (weil man oft mit RTTI bestimmen muss, welchen Typ man überhaupt hat), aber eben auch sehr multifunktionell.