Objektorientierte Modellierung, Einstieg
Eine Banking-App verwaltet Tausende Konten. Jedes hat einen Inhaber und ein Guthaben, und auf jedem kann man Geld einzahlen oder überweisen. Für jedes Konto eigene Variablen und eigene Programmteile zu schreiben, ginge nicht lange gut.
Die objektorientierte Programmierung löst das so: Du beschreibst einmal, wie ein Konto aufgebaut ist und was es kann, und erzeugst daraus beliebig viele Konten. Du lernst die Begriffe dafür und wie man den Entwurf zeichnet. Die Beispiele sind in Python geschrieben.
Objekt, Klasse, Attribut und Methode
Ein Objekt ist ein einzelnes Ding mit eigenen Daten und Fähigkeiten, zum Beispiel das Konto von Mia. Seine Daten heißen Attribute: Inhaber ist "Mia", Guthaben ist 50. Was es kann, heißt Methode: einzahlen, das Guthaben nennen.
Eine Klasse ist der Bauplan für Objekte gleicher Art, wie eine Backform für Kekse. Sie legt fest, welche Attribute und Methoden die Objekte haben. Ein Objekt heißt auch Instanz seiner Klasse. Die Klasse Konto gibt es einmal, Konten als Objekte beliebig oft, jedes mit eigenen Attributwerten.
Klasse und Konstruktor in Python
Ein Konstruktor ist eine besondere Methode, die beim Erzeugen eines Objekts läuft und die Attribute auf Startwerte setzt. In Python heißt er . Der Parameter steht für das Objekt, das gerade bearbeitet wird.
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 1 | 0 | |
| 2 | 1 | |
| 3 | 2 | |
| 4 | 2 | |
| 5 | 1 | |
| 6 | 2 | |
| 7 | 1 | |
| 8 | 2 |
Ein Objekt erzeugst du mit dem Namen der Klasse: ruft den Konstruktor auf. Methoden rufst du mit Punkt auf: . Der Unterstrich vor hat einen Grund, den du bei der Datenkapselung erfährst. In anderen Sprachen wie Java trägt der Konstruktor den Namen der Klasse.
Klassen als Datentypen und Referenzen
Eine Klasse ist ein selbst definierter Datentyp. steht neben und , und eine Variable kann ein Konto tragen. Die Variable enthält aber nicht das Objekt selbst, sondern eine Referenz, also einen Verweis darauf, wie eine Adresse auf einem Zettel.
Darum kopiert nur den Verweis. Danach zeigen beide Namen auf dasselbe Objekt, und eine Änderung über den einen Namen sieht man über den anderen. Ein neues Objekt entsteht nur, wenn du den Konstruktor aufrufst.
Kommunikation zwischen Objekten
Objekte arbeiten zusammen, indem eines eine Methode des anderen aufruft. Man sagt, es sendet ihm eine Nachricht. Wir ergänzen die Klasse Konto um eine Methode, die Geld an ein anderes Konto überweist (Umlaute lassen wir in Namen weg).
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 9 | 1 | |
| 10 | 2 | |
| 11 | 3 | |
| 12 | 3 |
Das Konto bucht den Betrag bei sich ab und sendet dem Zielkonto die Nachricht . Ist zu wenig Guthaben da, passiert nichts.
Objekte, Referenz und Überweisung
Objekte, Referenz und Überweisung
Welche drei Zahlen gibt dieses Programm aus?
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 1 | 0 | |
| 2 | 0 | |
| 3 | 0 | |
| 4 | 0 | |
| 5 | 0 | |
| 6 | 0 | |
| 7 | 0 |
Zeile 1 und 2 erzeugen zwei Objekte: Mia hat 50, Ben 20. Zeile 3 ruft nur für Mias Objekt auf: 50 + 30 = 80. Zeile 4 erzeugt kein neues Konto, zeigt auf Mias Objekt. Zeile 5 zahlt dort 10 ein: 80 + 10 = 90.
Zeile 6: 25 ist höchstens so groß wie 90, also wird gebucht. Mias Objekt hat danach 90 - 25 = 65, und Bens Objekt bekommt 20 + 25 = 45. Zeile 7 gibt 65, 45 und 65 aus. Mia und sind dasselbe Objekt, darum stehen dort gleiche Werte.
Datenkapselung
Datenkapselung heißt: Die Attribute eines Objekts sind von außen nicht frei zugänglich, man erreicht sie nur über Methoden. Die Methoden achten darauf, dass die Daten gültig bleiben. bucht nur ab, wenn genug Guthaben da ist. Könnte jedes Programmteil beliebig setzen, ließe sich diese Regel umgehen.
Python erzwingt das nicht. Ein Unterstrich vor dem Namen ist eine Vereinbarung: "Nicht von außen anfassen". Sprachen wie Java sperren den Zugriff mit dem Schlüsselwort .
UML-Klassendiagramm und Objektdiagramm
Entwürfe zeichnet man mit der UML (Unified Modeling Language), einer genormten Zeichensprache. Ein Klassendiagramm zeigt eine Klasse als Rechteck mit drei Fächern: Name, Attribute, Methoden. Ein Objektdiagramm zeigt ein einzelnes Objekt: oben "objektname : Klassenname" (unterstrichen), darunter die Attribute mit ihren Werten. Methoden fehlen, sie stehen in der Klasse. Ein Plus vor einem Eintrag heißt öffentlich, ein Minus heißt privat.
| Fach | Klassendiagramm | Objektdiagramm |
|---|---|---|
| Kopf | Konto | mia : Konto |
| Attribut | + inhaber : str | inhaber = "Mia" |
| Attribut | - guthaben : int | guthaben = 50 |
| Methode | + einzahlen(betrag) | fehlt |
| Methode | + ueberweisen(ziel, betrag) | fehlt |
| Methode | + guthaben() | fehlt |
Generalisierung, Spezialisierung, Vererbung und Polymorphismus
Hund und Katze haben beide einen Namen und können einen Laut von sich geben. Die Generalisierung fasst solches Gemeinsame in einer allgemeineren Oberklasse zusammen, hier Tier. Umgekehrt ist Hund eine Spezialisierung von Tier: eine Unterklasse, die mehr kann oder etwas anders macht.
Bei der Vererbung übernimmt die Unterklasse alle Attribute und Methoden der Oberklasse. Sie kann neue hinzufügen und geerbte überschreiben. In Python steht die Oberklasse in Klammern: . Zwischen beiden gilt die "ist ein"-Beziehung: Ein Hund ist ein Tier. Im UML-Diagramm führt ein Pfeil mit hohler Dreiecksspitze von der Unterklasse zur Oberklasse.
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 1 | 0 | |
| 2 | 1 | |
| 3 | 2 | |
| 4 | 1 | |
| 5 | 2 | |
| 6 | 0 | |
| 7 | 1 | |
| 8 | 2 | |
| 9 | 0 | |
| 10 | 1 | |
| 11 | 2 |
Hund und Katze erben den Konstruktor und das Attribut und überschreiben . Polymorphismus (Vielgestaltigkeit) heißt: Derselbe Aufruf bewirkt je nach Klasse des Objekts etwas anderes.
Derselbe Aufruf, anderes Verhalten
Derselbe Aufruf, anderes Verhalten
Zu den Klassen oben gehört dieses Programm:
| Zeile | Einrückung | Anweisung |
|---|---|---|
| 12 | 0 | |
| 13 | 0 | |
| 14 | 1 |
Was wird ausgegeben?
Die Schleife ruft für jedes Element auf, ohne die Klasse zu kennen. Python wählt die Methode passend zum Objekt: Beim Hund liefert sie "Wuff", bei der Katze "Miau", und das Tier ohne eigene Version nutzt die Methode der Oberklasse und liefert "...". Die Ausgabe lautet: Rex Wuff, Luna Miau, Fisch ...
Klasse und Objekt verwechseln
Klasse und Objekt verwechseln
„Konto ist ein Objekt, und Mias Konto ist die Klasse.“
Es ist umgekehrt. ist die Klasse, der Bauplan. Mias Konto ist ein Objekt, eine Instanz dieser Klasse. Aus einer Klasse entstehen beliebig viele Objekte.
Eine Zuweisung erzeugt ein neues Objekt
Eine Zuweisung erzeugt ein neues Objekt
„Mit habe ich ein zweites Konto mit demselben Guthaben.“
Es gibt weiterhin nur ein Objekt, und zwei Namen zeigen darauf. Ein zweites Konto entsteht nur mit einem neuen Aufruf des Konstruktors, etwa .
Vererbung bei "hat ein"
Vererbung bei "hat ein"
„Ein Auto hat Reifen, also ist Reifen eine Oberklasse von Auto.“
Vererbung passt nur bei "ist ein", wie bei Hund und Tier. Dass ein Auto Reifen hat, ist keine Vererbung. Die Klasse Auto bekommt dafür ein Attribut, das auf Reifen-Objekte verweist.
Zusammenfassung
Ein Objekt hat Attribute (Daten) und Methoden (Fähigkeiten). Eine Klasse ist der Bauplan, ein Objekt ist eine Instanz.
Der Konstruktor setzt beim Erzeugen die Startwerte. In Python heißt er .
Eine Klasse ist ein Datentyp. Eine Variable enthält nur eine Referenz auf das Objekt, eine Zuweisung kopiert den Verweis.
Objekte kommunizieren, indem eines Methoden des anderen aufruft.
Datenkapselung: Attribute sind nur über Methoden erreichbar, damit die Daten gültig bleiben.
Eine Unterklasse erbt von der Oberklasse und kann überschreiben. Polymorphismus heißt, derselbe Aufruf wirkt je nach Klasse anders.
Klassendiagramm: Name, Attribute, Methoden. Objektdiagramm: Objektname, Klasse und Attributwerte.
Übungen
Was ist eine Klasse?
Es läuft , dann , dann und dann . Welche Zahl gibt aus?
Es gilt und . Dann läuft und danach . Welche Zahl gibt am Ende aus?
Für welches Paar ist Vererbung sinnvoll?
In der Klasse Konto steht das Guthaben nur in , und prüft vor dem Abbuchen den Kontostand. Erkläre, welches Problem die Datenkapselung hier verhindert.