Code: Alles auswählen.
class lcl_1 defintion.
public section.
methods:
get_value_of_var_1 returning value(rv_var) type char01.
data: var2 type string.
private section.
data: var01 type char01.
endclass.
class lcl_1 implementation.
method get_value_of_var_1.
rv_var = var01.
endmethod.
endclass.
class lcl_2 definition.
public section.
methods: bla.
private section.
data: mv_bla type char01.
data: mv_bla_2 type string.
endclass.
class lcl_2 implementation.
method bla.
" erstelle das objekt der klasse
data(ref_1) = new lcl_1( ).
" nun hast du 2 möglichkeiten
" 1. über eine methode mit returning value - dies sollte bei attributen immer gemacht werden, wenn sie außerhalb verwendet werden sollen, denn man könnte in die methode get_value_of_var_1 eventuell eine berechtigungsprüfung einbauen oder änliches
mv_bla = ref_1->get_value_of_var_1( ).
" 2. über ein public ( öffentliches ) attribut - sollte eigentlich nie gemacht werden - aber möglich ist es. man kann es z. b. bei wirklich unkritischen sachen machen
mv_bla_2 = ref_1->var2.
endmethod.
endclass.
Folgende Benutzer bedankten sich beim Autor SaskuAc für den Beitrag:
Hotzenplotz
Code: Alles auswählen.
Klasse test1
*hier möchte ich den Wert der Variablen
ed_full exportieren, die vorher in der Methode der Klasse verändert wurde.
ed_full = 'x'.
Klasse test 2
*hier möchte ich den Wert der Variablen ed_full importieren, die vorher in der Klasse test 1 verändert wurde.
While ed_full is not inital "falls so möglich"
do this
Endwhile.
Siehe den Post SaskuAc: Du kannst einfach ein öffentliches Attribut der Klasse anlegen. Entweder als Instanz oder statisch. Somit brauchst du keine SETTER / GETTER.Abapsocke hat geschrieben:das mit Gettern und Settern ist mir schon klar, aber nur weil man etwas machen soll, muss es doch eine möglichkeit geben das zu umgehen, sonst wäre es ja unsinn zu lernen, wie man getter und Setter einsetzt, wenn man es ohnehin nicht ohne tun kann.
Ich vergleiche das immer gerne mit einem Bauplan. Bei der Objektinstanziierung wird dann das Objekt entsprechend der Vorlage (Klasse) erzeugt.Abapsocke hat geschrieben:und noch eine Frage: mit Type Ref to zeige ich im prinzip auf eine klasse, aber ohne wertübertragung? Also vom Verständnis her: du sollst so aussehen wie!
Mhh bei Klassenbasierten Ausnahmen wüsste ich grad nicht wie Hier hast du ja folgenden Aufbau:Abapsocke hat geschrieben:Alternativ.. gibt es ne Möglichkeit ein geraisdes Event mit einem If zu verbinden. In dem Sinne "wenn event x stattgefunden hat.. mache dies"
Code: Alles auswählen.
try.
* Mache was einen Dump Auslösen könnte
catch z_ex into data(lo_cx)
* Fange Dump ab.
* Hole Fehlernachricht.
data(lv_err_txt) = lo_cx->get_text( ).
endtry.
Code: Alles auswählen.
RAISE EXCEPTION TYPE Z_EX EXPORTING z_err_id = '1' textid = z_ex=>z_exerr_msg
Entweder exceptions ... oder aber direkt Events .. du kannst dazu dann handler Methoden definieren, die das Event vom Objekt abfangen und dann verarbeiten. und wenn du später dann mal wissen möchtest ob dieses oder jenes stattgefunden hat, kann man sich ja verschiedene Hilfsvariablen anlegen ( Eine Tabelle mit Eventnamen, variablen die Flags enthalten, usw. )Abapsocke hat geschrieben: Alternativ.. gibt es ne Möglichkeit ein geraisdes Event mit einem If zu verbinden. In dem Sinne "wenn event x stattgefunden hat.. mache dies"
Ich verstehe es, wenn Leute nicht OO-Programmieren wollen. Aber ich bestreite wehement, dass der Quellcode lesbarer wird, wenn man prozedural programmiert ... Meiner Meinung nach ist er dann seltenst gut strukturiert und ausreichend dokumentiert. Bei OO kann man anhand der Klassen super strukturieren und auch leichter dokumentieren ... Ich weiß nicht inwieweit du schon mit OO gearbeitet hast, aber ich glaube dir würde es generell gut gefallen, wenn du es einmal verstanden hast. Weil ab dann ist es wesentlich leichter - aber gut, ich will hier jetzt keine OO VS. Prozedural Diskussion anfachen, die haben wir hier schon oft genugDeathAndPain hat geschrieben:Oder einfach klassisch-prozedural programmieren, dann hat man den ganzen Stress nicht, und der Quellcode ist besser lesbar. *duckundweg*
okay, hier nochmal zwei kurze ( getrennte ) beispiele wie man auf attribute zugreifen kann.Abapsocke hat geschrieben:das mit Gettern und Settern ist mir schon klar, aber nur weil man etwas machen soll, muss es doch eine möglichkeit geben das zu umgehen, sonst wäre es ja unsinn zu lernen, wie man getter und Setter einsetzt, wenn man es ohnehin nicht ohne tun kann.
Defakto verstehe ich euch jetzt so: In dem Moment wo ich mit einer Klasse auf die Variablen und Constanten einer andere zugreifen will, muss ich mit Gettern und Settern arbeiten. D.H alle diese Werte kommen eigentlich ins Private.
Ok, dazu habe ich mir auch schon einiges angelesen, aber in dem konkreten Fall hilft mir das nicht weiter.
Ich brauche da wirklich ein konkretes Beispiel mit zwei Klassen. (hier ein bisschen pseudocode)
Code: Alles auswählen.
Klasse test1 *hier möchte ich den Wert der Variablen ed_full exportieren, die vorher in der Methode der Klasse verändert wurde. ed_full = 'x'. Klasse test 2 *hier möchte ich den Wert der Variablen ed_full importieren, die vorher in der Klasse test 1 verändert wurde. While ed_full is not inital "falls so möglich" do this Endwhile.
Code: Alles auswählen.
class class_1 definition.
public section.
" definiert ein öffentliches Instanzattribut, welches bei jedem neuem Objekt anders gespeichert ist.
data: var_01 type string.
" definiert ein statisches (Klassen-)Attribut, welches bei jedem Objekt gleich ist.
class-data: var_02 string.
endclass.
class class_1 implementation.
endclass.
class class_2 definition.
public section.
methods get_member_var.
methods get_static_var.
endclass.
class class_2 implementation.
method get_member_var.
" hier könnte man statt einer Inline Deklaration auch direkt eine existierende Variable ( z. B. im Definitionsbereich ) ansprechen
" das Wort 'new' erstellt ein neues objekt und gleichzeitig eine Referenz der Klasse class_1. Die Referenz und das Objekt werden allerdings nach diesem Statement gleich wieder gelöscht. ( weil die Referenz nirgends abgespeichert wird ... Daher macht das Beispiel theoretisch keinen Sinn .. verdeutlicht dennoch wie man etwas benutzen kann )
" ich würde hier gleich auf den Wert von var_01 gehen, ohne eine Methode aufzurufen.
data(local_var) = new class_1( )->var_01.
endmethod.
method get_static_var.
" hier greife ich auf das statische Attribut 'var_02' der Klasse 'class_1' zu ohne eine getter methode zu verwenden.
data( local_var) = class_1=>var_02.
endmehtod.
endclass.
Code: Alles auswählen.
class class_1 definition.
public section.
methods set_var_01 importing iv_01 type string.
methods get_var_01 returning value(rv_01) type string.
class-methods: set_var_02 importing iv_02 type string.
class-methods: get_var_02 returning value(rv_02) type string.
private section.
data: var_01 type string.
class-data: var_02 string.
endclass.
class class_1 implementation.
method set_var_01.
" eine einfache prüfung ob der wert überhaupt gesetzt werden soll
if strlen( iv_01 ) < 5.
var_01 = iv_01.
endif.
endmethod.
method get_var_01.
" z. b. irgend eine Berechtigungsprüfung
rv_01 = var_01.
endmethod.
method set_var_02.
" eine einfache prüfung ob der wert überhaupt gesetzt werden soll
" im prinzip aber das gleiche wie für Instanzattribute, nur dass dieser wert immer bestehen bleibt nachdem die Klasse ein mal verwendet worden ist im programm
if strlen( iv_02 ) < 10.
var_02 = iv_02.
endif.
endmethod.
method get_var_02.
" z. b. irgend eine Berechtigungsprüfung
" wieder im prinzip das gleiche wie für die Instanzattribute.
rv_02 = var_02.
endmethod.
endclass.
class class_2 definition.
public section.
" der wird ja bei jedem neuem objekt aufgerufen.
methods: constructor.
" wird bei jeder 1. Verwendung der Klasse in einem Programm verwendet.
class-methods: class_constructor.
endclass.
class class_2 implementation.
method constructor.
data(lo_class_1) = new class_1( ).
" jetzt ist var_01 von lo_class_1 noch leer und liefert nichts
data(lv_value) = lo_class_1->get_var_01( ).
lo_class_1->set_var_01( 'Test' ).
" jetzt steht in lv_value 'Test'. hätten wir z. B. Test123 mitgegeben in der SETTER wäre lv_value auch wieder leer, da durch unsere prüfung var_01 in class_1 nicht befüllt würde ( da mehr als 5 Zeichen )
lv_value = lo_class_1->get_var_01( ).
endmethod.
method class_constructor.
" hier bekommen wir dann 'test_stat' bei der getter Variable
class_1=>set_var_02( 'test_stat' ).
data(lv_value_stat) = class_1=>get_var_02( ).
endmethod.
endclass.
SaskuAc hat geschrieben:persönlich würde ich immer auf setter und getter setzen, da man zur not schnell eine prüfung einbauen kann, selbst wenn man aktuell keine braucht. Außerdem kann es bei der Vermeidung von Programmierfehlern helfen. Aber natürlich muss man nicht immer auf die Methoden setzen. Wenn ich jetzt einfache Variablen habe, die theoretisch irrelevant sind ( wobei sich ja dann die Frage stellt, warum man die überhaupt braucht ) mache ich das Attribut auch mal öffentlich.
Code: Alles auswählen.
DATA(materialart) = o_material->get_mara( )-mtart.
Dagegen gibt's jetzt was von Larsiohvam (Zumindest für den atom edtitor):SaskuAc hat geschrieben:PS: bitte wieder schreibfehler, falls vorhanden, im Code nicht beachten .. habe immer noch keinen Editor auf diesem PC ...
Mein Lieblingszitat: "I don’t know the answer but I do know that debugging what happens after pressing a command in VA01 is easier to follow than the equivalent in ME21N. Or is that just because I am an OO novice?"SaskuAc hat geschrieben:Ich verstehe es, wenn Leute nicht OO-Programmieren wollen. Aber ich bestreite wehement, dass der Quellcode lesbarer wird, wenn man prozedural programmiert ...
Dass das falsch ist, zeigt schon ein einfacher Vergleich zwischen Funktionsbausteinen und Methoden (Funktionsgruppen und Klassen haben ja technisch durchaus eine gewisse Ähnlichkeit und dienen letztlich demselben Zweck). Schau Dir an, wie Du bei Funktionsbausteinen Online-Doku hinterlegen kannst, bis hinunter zu Einzeldokus für jeden einzelnen Parameter, der im Interface direkt am Parameter angezeigt und dessen Existenz durch eine Lampe sichtbar gemacht wird. Und dann schau Dir im Vergleich Deine Dokumentationsmöglichkeiten bei Klassen und Methoden an. Da gibt es nur wenige Texte, die man hinterlegen kann, und die sind im Menü versteckt. Die Konsequenz ist auch offensichtlich, selbst wenn Du Dir SAP-Standard-Code anschaust: Wieviele Funktionsbausteine haben eine ordentliche Online-Doku, und wieviele Klassenmethoden haben eine solche?Meiner Meinung nach ist er dann seltenst gut strukturiert und ausreichend dokumentiert. Bei OO kann man anhand der Klassen super strukturieren und auch leichter dokumentieren ...
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Legxis
Bist du sicher, dass du hinreichend Erfahrung in prozeduraler Programmierung hast um derartige Aussagen zu treffen?SaskuAc hat geschrieben:[.... Aber ich bestreite wehement, dass der Quellcode lesbarer wird, wenn man prozedural programmiert ... Meiner Meinung nach ist er dann seltenst gut strukturiert und ausreichend dokumentiert. Bei OO kann man anhand der Klassen super strukturieren und auch leichter dokumentieren
Und das ist eine Frechheit!SaskuAc hat geschrieben:Ich weiß nicht inwieweit du schon mit OO gearbeitet hast, aber ich glaube dir würde es generell gut gefallen, wenn du es einmal verstanden hast.
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
ST22
Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag (Insgesamt 3):
a-dead-trousers • ST22 • 4byte
Stimme ich zu. Kann man schön mit Exceptions machenRalf.Wenzel hat geschrieben:Übrigens hat das Beispiel mit dem LOOP mir gezeigt, wie sehr ich inzwischen anders denke.
PERFORM...
Prüfung
PERFORM....
Prüfung
Wenn man gewohnt ist, Methoden zu schreiben, IST die Methode die Prüfung.
Haben wir hier auch. Dient für mich immer als Beispiel wie wichtig Strukur im Programm ist. Prozedual wie OO.Ralf.Wenzel hat geschrieben:Fakt ist aber, und da muss ich einigen Leuten hier recht geben, dass viele prozedural geschriebene Programme grausig sind. 10.000 Zeilen Coding, davon LOOPs die über 2.000 Zeilen gehen, da fällt dann ein GC_X vom Himmel oder ein Flag in SY-LISEL (das dann gleich kontextabhängig für alle möglichen Flags verwendet wird; man spart sich ja das Deklarieren), das dann plötzlich die Verarbeitung signifikant beeinflusst. Je älter das Coding ist, umso grausiger ist es in aller Regel.
Geht mir genauso. Dadurch das du weißt das der Rest funktioniert, kannst du direkt die Methode debuggen und kannst dir sicher sein, dass die auch beim mehrmaligen verwenden wieder richtig laufen wirdRalf.Wenzel hat geschrieben:Interessant ist, dass ich mich viel weniger im Debugger bewege, seit ich streng OO programmiere. Bestenfalls gehe ich zu einer bestimmten Stelle, um mir Werte im Debugger anzusehen, aber das "Durchhoppeln" habe ich mir fast komplett abgewöhnt
Verstehe ich nicht wieso das viele kritisieren. Das hat auch nichts speziell mit OO zu tun. Das kann doch genauso im Prozedualen genutzt werden. Ich "hasse" Methoden / Unterprogramme, die Eierlegende Wollmilchsau sind, da dann meistens nicht mehr erkennbar ist, was sie jetzt alles machen können/sollen. Ich gehe den Weg "Eine Funktionalität / Aufgabe = Eine Methode / Unterprogramm". Nicht mehr nicht weniger.Ralf.Wenzel hat geschrieben:Gerade die kritisierten vielen kleinen Methoden führen dazu, dass ich viel mehr auf Zusammenhänge achte als auf einzelne Anweisungen, denn Methoden decken quasi Gedankenschritte ab. Die o. g. Prüfmethode ist so ein Beispiel.
Folgende Benutzer bedankten sich beim Autor 4byte für den Beitrag:
ralf.wenzel
Wie fängt man einen Elefanten?ralf.wenzel hat geschrieben: Ich (Objekt "Ralf" der Klasse "Durstiger") rufe mit meiner Methode RALF->KAFFEE_WILL( ) nur die Methode DE_LONGHI->KAFFEE_ERZEUGEN( ) der Kaffeemaschine auf, indem ich auf den entsprechenden Knopf drücke. Wie die Maschine intern dafür sorgt, dass ich auch Kaffee bekomme und der bestimmte qualitative und quantitative Eigenschaften hat, kümmert mich nur beim Kauf (quasi dem Implementieren der Klasse).
Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag:
DeathAndPain