Um das Konzept der objektorientierten Programmierung in die Praxis zu übertragen, müssen wir zunächst einmal verstehen, was in Python Klassen und Objekte eigentlich sind. Genau das wirst du im heutigen Blogartikel Schritt für Schritt herausfinden!
Inhaltsverzeichnis
1. Wiederholung: Warum objektorientiert programmieren?
Im vergangenen Blogbeitrag haben wir uns bereits das grobe Konzept der objektorientierten Programmierung in der Theorie angesehen. Damit du dir das Ganze nun besser vorstellen und den Sinn hinter diesem Konzept erkennen kannst, gehen wir nun in die Praxis über.
Wie du bereits erfahren hast, können wir uns mit der objektorientierten Programmierung eigene Datentypen bauen, die komplexere Objekte repräsentieren. Programmieren wir also zum Beispiel ein Spiel, in welchem ein Auto fahren soll, ist es sinnvoll, für dieses einen eigenen Datentyp zu kreieren.
Wenn man in Python objektorientiert programmiert, baut man sich einen Datentyp, indem man eine sogenannte Klasse definiert. Dabei sind in Python Klassen nichts anderes als Baupläne. In solch einem Bauplan gibt man vor, wie ein Auto auszusehen hat.
2. Python Klassen definieren
Im ersten Schritt definieren wir also einmal eine Klasse für unser Auto. Dafür schreiben wir zunächst das Schlüsselwort class und anschließend den Namen der Klasse, also den Bezeichner. Da wir ein Auto modellieren möchten, nennen wir diese „Car“ und setzen im Anschluss einen Doppelpunkt.
Beim Drücken der Enter-Taste rückt PyCharm den Cursor darunter etwas ein. Alles, was wir nun eingerückt an dieser Stelle schreiben, gehört zur Definition der Klasse.
Was programmieren wir nun aber innerhalb dieser Klasse? Der Sinn einer Klasse ist, darin die Eigenschaften, die ein Auto besitzt, zu modellieren. Eine Eigenschaft (Attribut) könnte der Herstellername sein. Weitere Eigenschaften, die jedes Auto besitzt, sind beispielsweise die PS-Stärke und die Farbe. Diese Eigenschaften, die man in der Programmierung auch oftmals als Attribute bezeichnet, kann man nun in der Klasse festlegen.
2.1. Die init-Methode definieren
Bevor wir das umsetzen können, benötigen wir innerhalb der Klassendefinition nun eine ganz besondere Funktion. Und zwar die sogenannte init-Funktion.
Dafür schreiben wir für die Definition der Funktion zunächst das Schlüsselwort def. Da es sich um eine besondere Funktion handelt, müssen wir den Bezeichner exakt wie folgt wählen: __init__().
An dieser Stelle sehen wir, dass PyCharm die init-Funktion erkennt und automatisch den Doppelpunkt nach dem runden Klammerpaar ergänzt. Außerdem übergibt es innerhalb der Parameterliste einen noch unbekannten Parameter: Den Parameter self.
Was es genau mit dem self-Parameter auf sich hat, wirst du im nächsten Blogartikel erfahren. Wichtig ist für uns an dieser Stelle, dass wir die init-Funktion definiert haben und innerhalb ihres Funktionskörpers die Attribute definieren können, die das Auto innerhalb unseres Programms charakterisieren sollen.
Hierzu schreiben wir zuerst self, gefolgt von einem Punkt und dem Namen des Attributs, das wir definieren möchten. Da jedes Auto von einem Hersteller stammt, nennen wir das Attribut nun car_brand. Dieses Attribut kannst du dir wie eine Variable vorstellen. Da wir im Moment noch nicht wissen, welchen Wert wir darin speichern möchten, wählen wir den Wert None:
Anschließend definieren wir die PS-Stärke als weiteres Attribut und nennen dieses horse_power. Auch hier weisen wir den Wert None zu. Als drittes Attribut wählen wir noch die Farbe, nennen dieses color und speichern darin ebenfalls None:
Damit haben wir auch schon eine funktionsfähige Klasse in Python definiert! Diese stellt allerdings nur einen Bauplan dar. Führen wir das Programm nun aus, geschieht zunächst nichts. Bei Python Klassen verhält es sich nämlich wie bei Funktionen: Wenn man sie definiert, sie jedoch nicht aufruft, passiert auch nichts.
3. Objekte (Instanzen) von einer Klasse erzeugen
Mithilfe dieser Klasse bzw. mithilfe dieses Bauplans können wir nun eine Instanz, also ein sogenanntes Objekt vom Typ Car erstellen. Das funktioniert wie folgt:
Zunächst schreiben wir den Namen der Klasse (Car) und setzen anschließend ein Klammerpaar. Mit diesem simplen Befehl wird nun ein Objekt der Klasse Car erzeugt. Als Rückgabewert erhalten wir nun eine Referenz auf das neu erzeugte Objekt, welches wir in einer Variable speichern können. Diese Variable nennen wir in unserem Beispiel car1:
Das so generierte Objekt befindet sich nun im Speicher und als Rückgabewert erhalten wir die Referenz auf dieses Objekt. Diese Referenz speichern wir nun also in der Variable car1. Folglich können wir fortan über die Variable car1 auf das Objekt zugreifen.
Führen wir das Programm jetzt aus, geschieht Folgendes:
Zunächst wird die Klassendefinition gelesen. Dadurch ist Python nun bewusst, dass innerhalb dieses Programms eine selbstdefinierte Klasse mit dem Namen Car existiert.
Im Anschluss daran folgt der entscheidende Schritt, in dem wir die Klasse dazu nutzen, ein Objekt davon zu erzeugen. Dies erfolgt, indem wir den Klassennamen gefolgt von einem runden Klammerpaar schreiben.
Im Hintergrund wird nun ein Objekt erzeugt und dabei wird automatisch die init-Funktion der entsprechenden Klasse aufgerufen.
Hinweis: Innerhalb von Python Klassen spricht man nicht von Funktionen, sondern von sogenannten Methoden. Merke dir also einfach: Eine Methode ist das Gleiche wie eine Funktion, und oft wird sie auch mit dieser gleichgesetzt. Nimmt man es allerdings genau, ist eine Funktion nur eine Methode, wenn man diese innerhalb einer Klasse definiert. Präzise ausgedrückt handelt es sich also nicht um die init-Funktion, sondern um die init-Methode.
Der init-Methode übergeben wir nur einen Parameter – das self. Diesen geben wir bei der Definition einer Methode innerhalb einer Klasse in der Regel immer an. Daran erkennt man auch häufig auf den ersten Blick, ob es sich um eine Methode oder um eine Funktion handelt.
Wie bereits erwähnt, werden wir uns Genaueres zum self-Parameter erst im nächsten Artikel ansehen.
Nun werden innerhalb des Methodenkörpers die Attribute, die das Auto Objekt haben soll, erzeugt. Direkt zu Beginn wird diesen der Wert None zugewiesen.
4. Auf Attribute von Objekten zugreifen
Dass diese Attribute tatsächlich existieren, können wir direkt prüfen, indem wir über das neu erzeugte Objekt, dessen Referenz in car1 gespeichert ist, auf diese Attribute zugreifen.
Mithilfe der print-Funktion können wir uns beispielsweise eines der Attribute ausgeben lassen. Hierzu schreiben wir innerhalb der print-Funktion zunächst den Variablennamen, in welchem die Referenz auf das Objekt gespeichert ist. In unserem Fall ist das car1. Danach setzen wir einen Punkt und geben den entsprechenden Bezeichner des Attributs an. In unserem Beispiel greifen wir nun einmal auf das Attribut car_brand zu:
Führen wir das Ganze nun aus, gibt uns das Programm den Wert None aus:
Über die gleiche Schreibweise, über die wir gerade für die Ausgabe Zugriff auf das gewünschte Attribut erhalten haben, können wir diesem auch einen neuen Wert zuweisen.
Hierfür wählen wir beispielhaft „Audi“. Wenn wir dann die print-Anweisung dahinter setzen, sehen wir bei der Ausgabe, dass nun Audi darin gespeichert ist:
Mit den anderen Attributen können wir nun genauso vorgehen.
So legen wir einmal 250 PS und die Farbe „blau“ fest. Geben wir jetzt die einzelnen Attribute ebenfalls über die print-Funktion aus und führen das Programm aus, sehen wir, dass alle Attribute nun einen entsprechenden Wert enthalten:
Wir haben mit dem Objekt, auf welches über die Variable car1 referenziert wird, also einen Audi modelliert, der 250 PS und die Lackfarbe blau hat.
5. Von Python Klassen können mehrere Objekte erzeugt werden
Ein großer Vorteil, den wir nun haben, ist, dass wir mit der Klasse Car den allgemeinen Bauplan definiert haben. Wir können uns von diesem Bauplan also nicht nur ein Car-Objekt erzeugen, sondern beliebig viele! Möchten wir also ein weiteres Auto in unserem Programm, erzeugen wir einfach ein weiteres Objekt:
Nach dem Ausführen des Programms haben wir also zwei verschiedene Objekte:
6. Zusammenfassung
Der Blogartikel soll dir Folgendes vermitteln:
Die Klasse ist der übergreifende Bauplan. Dadurch können wir ganz individuell einen eigenen Datentyp nach unseren Wünschen kreieren. Mit der Definition der Klasse allein geschieht allerdings noch nichts, schließlich stellt sie lediglich einen Bauplan dar.
Wir müssen also von dieser Klasse noch konkrete Objekte erzeugen. Das funktioniert, indem wir den Klassennamen und ein rundes Klammerpaar dahinter schreiben. Jedes erzeugte Objekt ist jetzt für sich einzeln zu betrachten. Wir können also von der Klasse Car beliebig viele Auto Objekte erzeugen. Jedes Auto Objekt verfügt dann zwar über die gleichen Attribute, die Werte, die innerhalb der Attribute gespeichert sind, können jedoch für jedes Car Objekt unterschiedlich sein.
Damit hast du nun die Grundstruktur von Python Klassen und Objekten kennengelernt. Zu diesem Thema gibt es noch einiges mehr zu schreiben, da es komplex ist und zahlreiche Möglichkeiten bietet. In den kommenden Blogbeiträgen werden wir uns noch zum einen mit dem Thema self-Parameter und zum anderen mit Methoden und Klassen ausführlich beschäftigen.