Was ist OOP eigentlich?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 3. Dezember 2007, 18:46

Servus,

in diesem Thread stelle ich keine Frage sondern ein Thema zur Diskussion - was ist OOP?

Für mich ist OOP nicht nur die Sprache. Die Sprache, in unseren Fall Python bietet syntaktischen Zucker und einige angenehme Erleichterungen. Jedoch ist nicht jedes Programm welches Klassen etc. nutzt in meinen Augen objektorientiert. Um das zu veranschaulichen führe ich einen weiteren Begriff ein, objektnutzend. Objektnutzend ist ein Programm, welches Klassen und Instanzen nutzt (im Sinne von selbst definiert, nicht im sinne dass es Built-in Datentypen verwendet). Solch ein Programm zu schreiben ist recht trivial, denn man kann ganz normale Prozedurale Programme in Objektnutzende Programme umwandeln indem man einfach alle Funktionen in Klassen packt. Dadurch werden die Klassen zu ihrer Art Namensräumen, aber das Programm an sich nicht Objektorientiert. Man kann es auch in die andere Richtung drehen indem man Objektorientierte Programme schreibt in einer Programmiersprache die dafür keine zusätzliche Syntax bietet. Diesen Weg haben etwa die GTK+-Entwickler genommen.

Objektorientierung besteht nämlich aus zwei Worten: Objekt (diese werden in Objektnutzenden Programmen verwendet) und Orientierung. Letzteres ist kein sprachlicher Aspekt sondern ein gedanklicher. Er beschreibt, dass sich der Autor Gedanken darüber gemacht hat, die Dinge die er schreibt zu abstrahieren. D.h. eine Klasse macht genau das, was sie machen soll und kümmert sich um nichts anderes.

Nehmen wir mal ein eine Abwandlung eines Codes ich heute gesehen habe. Ein klassisches Beispiel ist die Klasse `Shape` mit ihren Kindklassen `Circle`, `Rectangle` und `Triangle`. Jede dieser Klassen hat ein `draw()` - ganz logisch, Formen sollen sich zeichnen können. Das ist OOP. Nun fügt der Autor der Klasse noch ein `react_on_network_interrupt()` hinzu, weil es dort gerade passt. Damit ist es in meinen Augen eigentlich kein Objektorientierter Entwurf mehr da `react_on_internet_interrupt()` teil der Programmlogik ist und nicht der Objektlogik (das setzt natürlich vorraus, das `react_on_network_interrupt` nicht tatsächlich sinnvoll ist, etwa das Objekt grün färbt, wenn Daten über das Netzwerk kommen). Wenn aber `react_on_network_interrupt` etwa da ist, das Programm zu beenden dann hat es im Objekt nichts verloren - dann gehört es raus.

Das ist nun vergleichsweise schwer zu erklären, denn es ist eben eine Gedankliche Sache, keine die wenn man es falsch macht Exceptions wirft. Es geht eben darum, dass man Instanzen als Daten eines Programmes verwendet und nicht als Funktionen die den Programmfluss bestimmen. Das ist nicht ganz einfach zu verstehen und Programmiersprachen wie Java führen meiner Meinung nach dazu, dass Objektorientiertes Design vernachlässigt wird - alles muss Klassen sein, also kann man Klassen dazu einspannen prozedural zu Programmieren.

Insgesamt ist Objektorientierte Programmierung ähnlich weit von Prozeduraler Programmierung entfernt wie Funktionale Programmierung nur gibt Objektnutzende Programmierung einem den Anschein, dass man die Konzepte von OOP verstanden hat - es funktioniert doch alles. Dies ist aber manchmal ein Trugschluss, da man dann manchmal solche Objekte konstruiert, dass sie einem mehr im Weg stehen als dass sie einem Helfem. Daher bin ich auch kein Fan des Übertragens von Prozeduralen Programmen nach "OOP", weil nicht alle prozeduralen Probleme Objektorientiert einfacher werden. Objektorientierung ist ein Werkzeug, kein Zwang. Wenn etwas Objektorientiert keinen Sinn ergibt, dann muss man das Problem da auch nicht reinzwingen.
OOP zu kennen ist jedoch eine gute Sache, auch wenn man es nicht unbedingt einsetzen muss - das ist wiederrum ähnlich wie grundlegende funktionale Konzepte zu kennen. Dieses Wissen bringt einem auf den ersten Blick nicht viel, aber langfristig kann es einem Helfen ein besserer Programmierer zu werden, indem man weiß, wie man an ein Problem rangehen kann.

Manchmal ist es aber auch sinnvoll oder notwendig Klassen zu schreiben die nicht Objektorientierten Design genügen, nur heißt das nicht dass das Programm dadurch OOP ist.

Das ist meiner Meinung nach das was in vielen Büchern zu kurz kommt und es ist auch verständlich, denn dass ist eben die Theorie und viele Bücher wollen Praxis vermitteln. Es ist auch gar nicht so einfach zu vermitteln, denn das Gefühl was OOP ist und was nicht kommt vermutlich auch erst nach einiger Praxis. Wobei, da warne ich gleich davor, man kann nicht immer genau sagen "Das ist OOP, weil..." und "Das ist kein OOP, weil...". Die Übergänge sind fließend und es kann auch sein dass eine Mischung von beiden an einer gegebenen Stelle optimal ist.

Das wären meine Gedanken zu OOP, würde mich freuen wenn noch jemand was zu ergänzen hätte oder seine Meinung darstellen will. Beispiele wären aber auch super :)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Montag 3. Dezember 2007, 20:03

fuer mich ist ein object nur ein namespace. Inklusive methoden, die mit diesen namespace arbeiten.

so ist es moeglich ein dictionary als namespace zu benutzen, funktionen koennen dan diesen namespace als argument uebergeben kriegen.
dieser kann dan als this/self fungieren.
und schon hat man OOP.

und wenn die funktionen im erwaehnten dictionary gebunden sind, hat man schon 3/4 der miete
cp != mv
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Montag 3. Dezember 2007, 20:09

Hi Leonidas

Wir haben in der Schule verschieden Fächer zum Thema programmieren besucht.
  • OOP (Objekt Orientiertes Programmieren) war eigentlich mehr Programmieren mit Java. Auch prozedurales Programmieren in Klasse ;)
  • Dann kam OOD (Objekt Orientiertes Design), da ging es um Vererbung, Polymorphismus etc.
  • Im 3. Semester kam ADS (Algorithmen und Datestrukturen), da kamen verschiedene Datenstrukturen (Hashmaps, Bäume, Graphen,...) und verschiedene Algorithmen die mit diesen Strukturen arbeiten.
  • Weiter geht es mit Software Entwicklung, da durften wir einem sehr langweiligen Dozenten über verschiedene Patterns(Observer,MVC,...), einige Programmierarten (XP, Wasserfall, Unified Process) zuhören.
  • Zurzeit ist JFF (Java Für Fortgeschrittene) an der Reihe, das mit Abstand schlimmste Fach :). Der erste Teil war sozusagen vorbereitung für den SCJP (Sun Zertifikat) Test, was aber gar nichts mit Programmieren selber zutun hat sondern mehr mit der EBNF von Java und der API selbst. Der zweite Teil ist ein wenig besser, da werden einzelne Teile der API durchgenommen (Networking, Security, ...).
Im Ganzen sehr viel Java :), was jedoch nicht heisst ich hätte ne klare Vorstellung was OOP ist. Für mich ist ein Code OOP wenn:
  • man die Klassenhierarchie braucht (Vererbung,...) und nicht nur die Klassen als Container für Methoden und Members braucht (was nicht heisst das ich es an gewissen Stellen nicht gut finde).
  • Design Patterns an passenden! Stellen gebraucht werden
  • im Klassendesing auch Dinge wie z.B. "low coupling" beachtet werden
Eine Unterscheidung zwischen OOP und anderen Programmierkonzepten kann man nicht eindeutig machen. Es sind gewisse Techniken die man im richtigen Mass (Wichtig!) einsetzen kann um Objekte sinnvoll und effizient zu gebrauchen.

Bis man OOP gut einsetzen kann, muss man glaub ich auch ein paar Mal so richtig auf die Fresse fallen beim programmieren. Da man meistens erst im Nachhinein die Vorteile und den Einsatzort so richtig sieht.


Gruss

PS: Seit ich das Fach JFF habe finde ich Java immer schlechter, da lernt man Dinge, die in Java syntaktisch gehen aber nie jemand so schreiben würde. So z.B. int[] test[]; einen zweidimensionalen Array erstellt oder das ganze Handling mit den Wrapperklassen (Stichwort widening/boxing).
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Montag 3. Dezember 2007, 20:32

Für mich als Programmieranfänger ist sowieso noch überhaupt kein Vorteil in der OOP ersichtlich...
Habe bisher nur mit JavaScript gearbeitet und dort auch ausschließlich funktional programmiert.

Bisher kann ich keine Vorteile im OOP sehen - vllt. ändert sich das ja auch noch. Mir helfen auch unzählige Tutorials nicht weiter den Vorteil genau zu erkennen... Entweder ich "denke anders" oder aber ich habe noch nicht ausreichen mit Python programmiert...
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Montag 3. Dezember 2007, 20:33

Ich hab n paar Fragen...
rayo hat geschrieben:Dann kam OOD (Objekt Orientiertes Design), da ging es um Vererbung, Polymorphismus etc.
Kannst du (falls das möglich ist :D ) kurz erklären, was Polymorphismus ist? Darüber habe ich zwar auch etwas in einem Buch geselen
(warum "auch" ? Darum: Klickmich! ) , aber da wurde es halt nur kurz erwähnt... und schon der Begriff hörte sich interessant an, so wie die Beschreibung ebenjenes...
Nur leider war das im Buch halt nicht so genau...
Zuletzt geändert von Vingdoloras am Dienstag 4. Dezember 2007, 15:19, insgesamt 1-mal geändert.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Montag 3. Dezember 2007, 20:50

Hi

Also zuerstmal den englischen Wikieintrag dazu: http://en.wikipedia.org/wiki/Polymorphi ... in_Python:
Hat sogar Beispiele in Python.

Polymorphismus ist (glaub ich mal) wenn verschiedene Objekte gleiche Methoden haben aber in diesen Methoden andere Sachen machen (überschriebene oder überladene Methoden)

Wie auf der Wikiseite beschrieben macht Python davon regen Gebrauch, da z.B. eine Liste und ein String gleich angesprochen wird (str[x], list[x])

Ein beliebtes Beispiel (auch im Wiki) ist auch Animals als Oberklasse und verschiedene Tiere als Unterklassen (Vererbt, überschriebene Methoden). Jedes Tier kann z.B. laut_geben(), jedoch macht das jedes Tier anders, wenn man aber jetzt ein_animal.laut_geben() macht, muss man sich nicht darum kümmern ob es nun eine Katze oder ein Hund ist.

War das irgendwie Verständlich?

Gruss
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Montag 3. Dezember 2007, 20:58

eine rudimentaere oop implementation:
zeigt aber wie simple es sein kann:

Code: Alles auswählen


#oop iplementation
def oop_new(toinit, *args, **kw):
	oop_getmethod(toinit, "initialize")(*args, **kw)
	return toinit
def oop_getmethod(obj, attr):
	def tmp(*args, **kw):
		return obj[attr](obj, *args, **kw)
	return tmp
def oop_setattr(obj, attr, val):
	obj[attr] = val
def oop_getattr(obj, attr):
	return obj[attr]
def oop_mk_class(*methods):
	retval = {}
	for i in methods:
		#del vars()[i.__name__] #programmierer kommentieren ihre probleme einfach aus und gut is! (-;
		retval[i.__name__] = i
	return retval




#class Car
def initialize(me, name):
	oop_setattr(me, 'name', name)
	oop_setattr(me, 'speed', 0)
def faster(me):
	oop_setattr(me, "speed", oop_getattr(me, "speed") + 5)
def stop(me):
	oop_setattr(me, "speed", 0)
def to_str(me):
	return oop_getattr(me, "name") + ": " + str(oop_getattr(me, 'speed'))
Car = oop_mk_class(initialize, faster, stop, to_str)





#test
car1 = oop_new(Car, "hosday")
print oop_getmethod(car1, 'to_str')()

car2 = oop_new(Car, 'humaditzy')
for i in xrange(5):
	oop_getmethod(car2, "faster")()
print oop_getmethod(car2, 'to_str')()


cp != mv
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Montag 3. Dezember 2007, 21:11

Hi Costi

Das ist für mich eine rudimentäre Objekt Implementation und das hat nichts zu tun mit OOP.

Das konnte man auch in C mit Structs machen (Container für Daten und Methoden).

Gruss
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Montag 3. Dezember 2007, 21:28

Da ich mich gerade mit libpurple rumschlage muss ich da gleich mal OOP in C einwerfen. Denn die Alternative zu OOP oder dem, was ich drunter verstehe sind GOTO und globale Variablen :-)
Drupal nutzt GoF Patterns bis zum Abwinken, hat aber keine einzige Klasse. Schaut sich aus wie ein glib Programm, halt in PHP. Gleiches gilt für so ziemlich alle glib Libraries/Programme.

Selbst bei funktionaler Programmierung musst du deine Daten wo ablegen. Und ob man da jetzt Closures für verwendet, oder Dicts, oder Objekte ist einerlei. Das was Java/C++ aus OOP gemacht haben muss sich halt ausblenden.

Also von meiner Sichtweise: OOP lässt sich gar nicht vermeiden :-)
TUFKAB – the user formerly known as blackbird
Jona
User
Beiträge: 94
Registriert: Sonntag 23. September 2007, 23:25

Montag 3. Dezember 2007, 21:31

das schöne an OOP oder genauer OODesign ist für mich, dass ich die wirklichkeit so schön intuitiv abbilden kann:
durch vererbung, aggregation, komposition.
und natürlich haben die einzelnen objekte eigenschaften und fähigkeiten.
lässt man die einzelnen objekte wirklich nur die eigenschaften, fähigkeiten und relationen haben, die sie im zugrundeliegenden problem/aufgabe haben (und benennt man diese treffend - schwerer als man meint), wird das programm sehr schlüssig und leicht nachvollziehbar.

hier finde ich deine anmerkung ganz wichtig:
Nehmen wir mal ein eine Abwandlung eines Codes ich heute gesehen habe. Ein klassisches Beispiel ist die Klasse `Shape` mit ihren Kindklassen `Circle`, `Rectangle` und `Triangle`. Jede dieser Klassen hat ein `draw()` - ganz logisch, Formen sollen sich zeichnen können. Das ist OOP. Nun fügt der Autor der Klasse noch ein `react_on_network_interrupt()` hinzu, weil es dort gerade passt. Damit ist es in meinen Augen eigentlich kein Objektorientierter Entwurf mehr da `react_on_internet_interrupt()` teil der Programmlogik ist und nicht der Objektlogik (das setzt natürlich vorraus, das `react_on_network_interrupt` nicht tatsächlich sinnvoll ist, etwa das Objekt grün färbt, wenn Daten über das Netzwerk kommen). Wenn aber `react_on_network_interrupt` etwa da ist, das Programm zu beenden dann hat es im Objekt nichts verloren - dann gehört es raus
genau!

das gehört so eigentlich in jedes lehrbuch, habe ich aber noch nie gesehen. muss man anscheinend auf die harte tour lernen!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 3. Dezember 2007, 21:34

Zum Thema Polymorphismus ist der QListView Container imho ein super Beispiel imho: Kann eben jede Art von Items aufnehmen - nicht nur die Basis-Items. Dadurch kann man so ziemlich alles darin realisieren, vom optischen Schmankerl, bis hin zu Funktionalitäten im Backendbereich der Objekte.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Dienstag 4. Dezember 2007, 10:29

Hoi Leonidas,

vorweg: Ich bin weder Mathematiker noch Informatiker und doch weiß ich einen schönen Beweis und eleganten Code zu schätzen. Aber Vertreter beider Disziplinen übertreiben manchmal etwas (was innerhalb der Disziplin völlig ok ist) und so werden sie außerhalb oft mißverstanden und die schönsten ihrer Leistungen werden gar nicht gesehen. (Im Alltag schreibe ich bei beiden Anwendungen lieber ein paar Zeilen mehr - was durchaus dem Zen von Python entspricht ;-) .)
Und so möchte ich - was ich als Naturwissenschaftler eher selten machen - ein eher emphatisches Argument einwerfen:

Um es etwas weniger abstrakt zu machen nehmen wir mal eine Klasse "Auto" und eine Instanz "wagen". Da ist es nur natürlich den Wagen so zu bedienen: wagen.links_abbiegen(). Bei wagen.färben() fangen die Probleme schon an. Der Wagen färbt sich ja nicht selbst, oder? Also: färben(wagen).
Jetzt soll unser Auto aber kein alltägliches, stinkendes Blechmonster sein, sondern ein knuffiges Auto mit Kulleraugen in einem Kinderspiel. Da wird wagen.färben() oder .pinseln() schon eingängiger, nicht wahr? Es ist aber im Zweifel dieselbe Methode. (Das Argument läßt sich immer weiter treiben, je mehr man sich vom Abstraktem zum Intentionellem bewegt, es ist also eingentlich ein furchtbares auf Regression fußendes Argument, was ich gerne zugebe.)

In der Praxis entscheide ich nach "Bauchgefühl" (was ich in meiner Disziplin sonst eher nicht wage!): Was ist eher Verständlich aus Anwenderperspektive? Was werde ich in einem halben Jahr noch verstehen? In meinem aktuellen Projekt hätte ein Informatiker wahrscheinlich grid_search(model_instance) anstelle von model_instance.grid_search() geschrieben. Aber ich fühle mich sehr wohl mit *meiner* Lösung. (Dennoch: Gerne auch mehr konzeptionelle Kritik - ich bin da durchaus offen.)

Durchbreche ich damit Paradigmen? Ja, und?

Gruß,
Christian
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Dienstag 4. Dezember 2007, 11:47

Leonidas hat geschrieben:Um das zu veranschaulichen führe ich einen weiteren Begriff ein, objektnutzend.
Das halte ich für eine gute Unterscheidung, die sich echt mal in einigen Büchern wiederfinden sollte.
Es geht eben darum, dass man Instanzen als Daten eines Programmes verwendet und nicht als Funktionen die den Programmfluss bestimmen.
Zustimmung. In einem Blog oder so hab ich mal folgendes gefunden: "Wenn du deinen Klassen Namen wie Manager, Handler, etc gibst, denke erstmal nach. Objekte sollen Dinge, sein keine Tätigkeiten sein. Wenn Klassennamen dauernd substantivierte Verben sind, ist das ein Warnhinweis".
Ist natürlich nicht 100% gültig, ich wette, jeder von uns kennt einen Manager, der seine Berechtigung hat, aber als Anhaltspunkt imho echt gut.
Jan-Peer
User
Beiträge: 166
Registriert: Dienstag 2. Oktober 2007, 10:55

Dienstag 4. Dezember 2007, 11:49

Ich glaube, einer der wichtigsten Vorteile von OOP ist die Skalierbarkeit.

(Blödes Beispiel):
Ein Autorennspiel mit drei Wagen lässt sich natürlich auch mit funktionaler Programmierung schön realisieren. Nun ist der Code fertig, und irgendwer will plötzlich x Wagen mehr auf der Strecke sehen. Wenn du dein Programm mit OOP sorgfältig designt hast, muß du jetzt nur irgendwo eine einzige Zahl ändern. Beim funktionalen Ansatz dürfte es ein wenig aufwendiger werden ...
BlackJack

Dienstag 4. Dezember 2007, 12:10

@keppla: Unser "Algorithmen und Programmieren" Prof hat "objektbasiert" zu Programmen gesagt, die zwar Objekte benutzt haben, aber nicht wirklich objektorientiert waren. Ist IMHO eine recht treffende Bezeichnung. Die auch auf Python super passt, denn selbst wenn man nur klassisch prozedural arbeitet, wobei ich Klassen als `struct`/`RECORD`/`Type`-Ersatz noch zu "prozedural" zähle, so basiert trotzdem alles auf Objekten.

@Jan-Peer: Das Beispiel ist wirklich nicht so glücklich, denn wenn ich das in Haskell oder C programmiere, brauche ich auch nur irgendwo eine Zahl für die Wagen ändern.

Aber mit der Skalierbarkeit stimme ich Dir zu. Das ist IMHO auch der Grund warum es so schwer ist einfache Beispiele für Anfänger zu finden, weil die Vorteile von OOP erst so richtig zum tragen kommen, wenn man ein grösseres System vor sich hat. Was nicht heisst, dass man OOP deshalb nicht im "Kleinen" einsetzen sollte, weil Programme, wenn sie nützlich sind, die Eigenschaft haben, solange zu wachsen bis sie komplex genug sind um aus OOP Vorteile zu ziehen. Und wenn man an dem Punkt angekommen ist, möchte man ungern alles nochmal neu programmieren. :-)

Ein gutes und vor allem *praktisches* Beispiel ─ ich hasse diese albernen, konstriuerten Tier-, Geometrische-Figuren und Bankkonto-Beispiele ─ sind GUIs. Da hat man sinnvolle Beispiele für Vererbung (alles genmeinsame in eine Widget-Klasse packen) und Polymorphie (in ein Container-Widget kann man beliebige andere Widgets stecken).
Antworten