Kleines Einmaleins der Objektorientierung in a Nutshell for Dummies, mit Pferden!

if (question.about(PowerPoint, C++, LaTeX, Word, Excel...) == true) then question.answered(here);
Antworten
Benutzeravatar

Themenstarter
Knopfloch Weiblich
Administrator
Beiträge: 4914
Registriert: Mi 18. Nov 2015, 21:49

Kleines Einmaleins der Objektorientierung in a Nutshell for Dummies, mit Pferden!

Beitrag von Knopfloch »

@Libby:

1. Es gibt Klassen und Objekte.
Eine Klasse ist die allgemeine Beschreibung von bestimmten konkreten Dingen, diese konkreten Dinge sind die Objekte. Es gibt also z.B. eine Klasse Pferd, da ist definiert was ein Pferd kann, z.B. die Methoden Galopp(), Trab(), Schritt() und die Eigenschaften Stockmaß, Fellfarbe, Haarfarbe, Geburtstag (und eine passende Methode Alter()), biologisches Geschlecht, Identitätsgeschlecht, Hunger, Erschöpfung, Standort-Koordinaten.
Was das Pferd bei den Gangarten macht, ist für alle Pferde gleich, es wird aber z.B. das Alter, die aktuelle Erschöpfung und wahrscheinlich das Stockmaß einbezogen um die Geschwindigkeit zu berechnen.

Natürlich haben aber nicht alle Pferde den gleichen Geburtstag und so, daher ist jedes individuelle Pferd ein Objekt bzw. eine Instanz der Klasse Pferd.
In jedem Objekt werden dann die Eigenschaften unterschiedlich gesetzt und gespeichert.
So kommts dann, dass man vom Objekt HoneyFlowerFollowTheStars (Stockmaß 169, 12 Jahre alt) und vom Objekt MileyOReillyDreamOfAMustang (Stockmaß 180, 7 Jahre) die Methode Galopp() aufruft und beide unterschiedlich weit kommen.

Was die Variablen betriffft, ist ein Objekt damit nicht viel mehr als ein Python-Dictionary oder eine Java/C++-Map (also Liste von Schlüssel-Wert-Paaren) mit durch die Klassendefinition fest definierten Schlüsseln und unterschiedlichen Datentypen der Einträge. In Python wird das deshalb auch genauso gehandhabt und Objektorientierung ist dort nur eine schönere Schreibweise für Arbeiten mit einem Dictionary.

2. Das weitere wichtige Konzept ist Vererbung. Pferde lassen sich in Unterklassen aufteilen, die gemeinsame Eigenschaften haben, die man nicht jedesmal für jedes individuelle Objekt setzen möchte. Z.B. setzt dann halt die spezialisierte Klasse Haflinger die Werte von Fell- und Haarfarbe direkt auf Braun und Blond, sodass man in Instanzen der Haflinger-Klasse die Farbe nicht mehr selbst setzen muss. Die Klasse Islandpony führt dafür noch eine weitere Methode Tölt() ein, so können nur Instanzen des Islandponys tölten, alle anderen Pferde nicht. In manchen Programmiersprachen ist Mehrfachvererbung erlaubt, um Mischwesen wie den Island-Haflinger zu kreieren, das kann aber leicht zu Problemen führen (wenn bspw. beide Klassen die Farbe festlegen, welche wird dann genommen?).
Genauso kann man auf der anderen Seite Generalisierungen vornehmen, ein Pferd ist z.B. ein Tier, ein Tier ist ein Lebewesen, ein lebewesen ist irgendein begreifliches Ding in der Welt.
Schon ein begreifliches Ding hat dann z.B. eine Position in der Welt, sodass das Tier und das Pferd diese Variablen nicht mehr einführen müssen, und jedes Lebewesen oder zumindest jedes Tier hat schon den Geburtstag und das Alter().

Klassen können nicht nur Variablen auf andre (initiale) Werte setzen und neue Methoden einführen, sondern auch geerbte Methoden verändern, so unterscheidet sich der Galopp eines Roboterpferds vielleicht so grundlegend von dem des lebendigen Pferd, dass die Geschwindigkeit ganz anders berechnet werden muss, z.B. unabhängig vom Alter. Es ist aber fraglich, ob die Klasse Roboterpferd von Pferd ableiten sollte, da Pferd ja schon von lebewesen ableitet und ein Roboter doch eindeutig kein Lebewesen ist, auf der anderen Seite aber genau die Methoden anbietet, die ein Pferd so kann... solche Probleme sind dann die Freuden des objektorientierten Designs.

3. Objektorientiert programmieren tut man, indem man sich zunächst eben eine für das Problem passende Klassenhierarchie ausdenkt und dann Objekte von Klassen instanziiert, die Syntax ist dafür jeweils unterschiedlich, aber ungefähr sowas:

Code: Alles auswählen

WinnieThePooNotaBearButAHorse = new Pferd() //Neues Pferd instanziieren, setzt wahrscheinlich automatisch auch den Geburtstag auf heute
WinnieThePooNotaBearButAHorse.stockmaß = 150
WinnieThePooNotaBearButAHorse.position = Point(0,0)
WinnieThePooNotaBearButAHorse.Galopp()
print(WinnieThePooNotaBearButAHorse.position) //gibt z.B. (100,0) aus, weil es durch einen Galopp-Aufruf 100m weit galoppiert ist
WinnieThePooNotaBearButAHorse.stockmaß = 140 //seltsam, es schrumpft!?
WinnieThePooNotaBearButAHorse.Galopp() //jetzt gehts vllt. nur noch 80m weit
Manche Sprachen sind so durch und durch objektorientiert, dass schon die Anwendung an sich eine Klasse ist, die dann meistens eine ausgezeichnete Methode als Einsprungpunkt enthält, wie "main()".

In vielen Sprachen kann man die Sichtbarkeit von Variablen einschränken, z.B. könnte man hier das Stockmaß und den Geburtstag nur für die Klasse selbst und ihre Erben sichtbar machen, damit ich nicht bei Benutzung wie oben im Beispiel einfach das Stockmaß ändern kann, sondern würde es dann nur im Konstruktor, also bei "new Pferd()" als Parameter mit angeben, oder nichtmal das, wenn z.B. die Klasse Pony das Stockmaß schon selbst vorgibt und komplett verbieten will, dass mans ändert.

Wenn man ein Objekt nicht mehr braucht, kann man es löschen (in manchen Sprachen explizit, in manchen einfach dadurch, dass man nur eine lokale Variable verwendet hat o.ä.), damit der Speicherplatz für die Variablen wieder freigegeben wird.

Der Unterschied zwischen objektorientierter Programmierung (OOP) und Nicht-OOP sieht z.B. so aus:
Nicht-OOP:

Code: Alles auswählen

pferd1alter = 12
pferd1stockmaß = 150
pferd1erschöpfung = 50
pferd1pos = (0,0)
pferd2alter = 20
pferd2stockmaß = 160
pferd2erschöpfung = 20
pferd2pos = (0,0)
pferd1pos = Galopp(pferd1pos, pferd1alter, pferd1stockmaß, pferd1erschöpfung)
pferd2pos = Galopp(pferd2pos, pferd2alter, pferd2stockmaß, pferd2erschöpfung)
pferd3stockmaß = 160
pferd3fell = braun
pferd3haar = blond
ZeichnePferd(pferd3stockmaß, pferd3fell, pferd3haar)
OOP:

Code: Alles auswählen

pferd1 = Pferd(alter=12, stockmaß=150)
pferd1.erschöpfung=50
pferd2 = Pferd(alter=20, stockmaß=160)
pferd2.erschöpfung=20
pferd1.Galopp()
pferd2.Galopp()
pferd3 = Haflinger(stockmaß=160) //Farben setzt die Klasse Haflinger automatisch
pferd3.Zeichne()
Übungs-Aufgabe für den angehenden Programmierer: Male einen Haflinger!
Antworten