Post by Ralf UllrichErstmal musst du definieren, was OOP überhaupt ausmacht.
0 Ein Versuch dazu:
http://www.purl.org/stefan_ram/pub/begriff_objektorientierte_programmierung_de
Post by Ralf UllrichIn C kann man z.B. mit Zeigern auf Funktionen und structs sehr
wohl schon objektorientiert programmieren, auch wenn einem der
Compiler dabei keine schöne Syntax bietet oder bei der
Einhaltung der (selbstgesetzten) Regeln unterstützt.
1 Bei meinen heutigen Versuchen, C structs zu schreiben
(vorheriges posting), habe ich schon einen Vorteil einiger
objektorientierter Sprachen kennengelernt: Man kann die
Semantik der Beziehung zweier Typen (Obertyp oder Aggregation)
deutlicher unterscheiden als in C. Allerdings muß das nicht
eine Eigenschaft der objektorientierten Programmierung sein,
sondern kann auch eine »Zugabe« dieser Sprachen sein.
Post by Ralf UllrichAuch in Pascal habe ich damals, lange bevor es mit Turbo Pascal
5 einen objektorientierten Dialekt davon gab, bereits
weitgehend objektorientiert gearbeitet.
Wenn man in C gegen die Amiga-API oder Win32 programmiert,
wird man schon mit Dingen konfrontiert, die man als
»objektorientiert« empfindet. Jemand erwähnte vorhin die
Schnittstellen: Da ist es beispielsweise so, daß alle
Amige-Gerätetreiber eine Schnittstelle implementieren, indem
Einträge, die in der Sprungtabelle am Anfang an der gleichen
Stelle stehen dieselbe Bedeutung haben. - Das ist auch auf
der Maschinensprachenebene zu sehen. - Oder »Fensterklassen«
in der Windows-API.
Post by Ralf Ullrich- Top-Level Klassen sind final,
Also keine Vererbung. Die könnte man durch Aggregation
noch nachbilden, was aber weniger klar wäre.
In Absatz 1 erwähnte ich das schon, allerdings wirft die
Quelle aus Absatz 0 die Frage auf, ob Vererbung zum Kern
der objektorientierten Programmierung gehört.
Post by Ralf Ullrichhaben nur einen private no-arg Konstruktor
Das verhindert Exemplarbildung, die allerdings in
nicht-objektorientierten Sprachen auch möglich ist.
»records« in Pascal, oder in C:
struct example * e = malloc( sizeof( struct example )); if( e ) ...
Post by Ralf Ullrichund alle Methoden und Variablen darin sind statisch.
Die Bildung von Exemplaren zu record/struct-Typen ist
in Pascal und C auch möglich (vielleicht schon in
Algol 68) und daher vielleicht nicht unbedingt spezifisch
»objektorientiert«.
Post by Ralf Ullrich==> Damit sind Top-Level-Klassen im wesentlichen darauf
reduziert ein Namensraum zu sein, ähnlich z.b. den Units in
Pascal.
Ja, mir ist schon aufgefallen: Einige Vorteile, die ich
bisher der objektorientierten Programmierung zuschrieb,
gehören zur modularen Programmierung. Die Empfehlungen
für Kohäsion und Kapselung kann man nämlich erst einmal
auch auf Module oder abstrakte Datentypen münzen. Und
entsprechend bestimmte Vorteile der Strukturierung mit
Klassen.
Post by Ralf Ullrichdarin zeigt sich übrigens das Kapselung keine ausschließliche
Eigenschaft von OOP ist, sondern schon lange vorher in Gebrauch
war.
Genau an so etwas dachte ich.
Die Frage ist nämlich, was dann wirklich spezifisch
Objekt-Orientiert ist.
Post by Ralf Ullrich- Als abstrakte Datentypen sind zunächst Arrays erlaubt.
Die könnte man auch »Behältertypen« nennen, da sie auch eine
Implementation haben - die ein abstrakter Datentyp WIMRE nicht
haben müßte.
Post by Ralf Ullrich(Das macht aus den Exemplaren effektiv "Nicht-Objekte"
indem für alle Objects garantierte Funktionalität entfernt
wird. Das soll u.a. praktisch verhindern, dass man sie
in Collections verwendet, )
Wobei man vielleicht auch in der prozeduralen Programmierung
zu Datensätzen universelle »toString«- und
»hashCode«-Funktionen schreiben kann.
In C wäre es aber ein Problem, daß ein Datensatz zur Laufzeit
seinen Typ nicht immer kennt - nicht einmal seine Größe.
Das macht solche universellen Funktionen doch unmöglich.
Man könnte daher in die Definition von objektorientierter
Programmierung vielleicht noch aufnehmen, daß
Laufzeittypinformationen (implizit oder explizit) unterstützt
werden und mindestens verwendet werden können, um passende
Programmteile auszuwählen und im allgemeinen auch die Größe
eines Objekts zur Laufzeit implizit oder explizit erfahren
werden kann.
Post by Ralf UllrichSchreibe ein Konsolenprogramm, das ein automatisches
Schachbrett realisiert. Das heißt, die aktuelle Stellung soll
ausgegeben werden und dann der nächste Zug vom Benutzer erfragt
werden. Dieser Zug soll anhand der bekannten Schachregeln auf
Zulässigkeit geprüft werden, und nur angenommen und
durchgeführt werden, wenn er erlaubt ist. Das Programm muss
(schon wegen der Prüfung der Züge) Schachdrohungen erkennen,
muss aber nicht unbedingt ein Matt erkennen können.
Das ist nicht ganz so einfach, wie ich erhofft hatte, aber
vielleicht geht es wirklich nicht unter einer gewissen
Komplexität. Wenn ich mehr Zeit habe, komme ich vielleicht
noch einmal auf diese Aufgabe zurück.
Post by Ralf UllrichVergleicht man am Ende beide Lösungen, wird man IMHO
feststellen, dass die objektorientierte Lösung auf natürliche
Weise den Code gemäß den zu lösenden Teilaufgaben strukturiert,
während dies beim prozeduralen Vorgehen nur passiert, wenn der
Programmierer dies selbst herbeiführt. (Wenn er das aber tut,
kann sein Code genauso aufgeräumt und leserlich wirken, wie der
objektorientierte.)
Wenn ich einmal mehr Zeit habe, dann würde ich das gerne
einmal ausprobieren. Ich komme aber nicht gleich dazu.
Post by Ralf UllrichZusätzlich könnte man auch noch bewerten wie stark die
Eingriffe ins fertige Programm sind, wenn es anschließend so
erweitert werden soll, dass man am Beginn auswählen kann ob man
eine Partie normales Schach oder eine Partie Räuberschach
spielen will (und das Programm dann dessen deutlich andere
Regeln forcieren muss).
Ja, das könnte ein Punkt sein.
Ich habe schon einmal versucht, aufzuschreiben, warum die
objektorientierte Programmierung dann vorteilhaft ist, aber
dort fehlt noch ein Beispiel und weitere Ausarbeitung,
weswegen dieser Artikel derzeit vielleicht noch nicht gut
lesbar ist.
http://www.purl.org/stefan_ram/pub/warum-objektorientierte-programmierung