Der Begriff Objektorientierung beschreibt ein Programmierparadigma, mit dem die Konsistenz von Datenobjekten gesichert
werden kann und das die Wiederverwendbarkeit von Quellcode verbessert. Diese Vorteile werden dadurch erreicht, dass
man Datenstrukturen und die dazugehörigen Operationen zu einem Objekt zusammenfasst und den Zugriff auf diese
Strukturen nur über bestimmte Schnittstellen erlaubt.
Dabei werden die Daten eines solchen Objekts Attribute und die Verarbeitungsfunktionen Methoden genannt.
Attribute und Methoden werden unter dem Begriff Member einer Klasse zusammengefasst.
Objekte werden über Klassen erzeugt. Eine Klasse ist dabei eine formale Beschreibung der Struktur eines Objets, die
besagt, welche Attribute und Methoden es besitzt.
Instanzen der Klasse werden instanziiert. Es kann mehrere Instanzen einer Klasse geben.
Die einfachste Klasse hat weder Methoden noch Attribute und wird folgendermaßen definiert:
Beispiel:
class Konto:
pass
Im Prinzip unterscheidet sich eine Methode nur durch zwei Aspekte von einer Funktion:
Der Konstruktor einer Klasse ist eine spezielle Methode, die automatisch beim Instanziieren eines Objekts
aufgerufen wird, um das Objekt in einen gültigen Initialzustand zu versetzen. Die Methode muss mit dem Namen
__init__ definiert werden.
Beispiel:
class Beispielklasse:
def __init__(self):
print("Hier spricht der Konstruktor")
Da es die Hauptaufgabe eines Konstruktors ist, einen konsistenten Initialzustand der Instanz herzustellen,
sollten alle Attribute einer Klasse auch dort definiert werden.
Beispiel:
def __init__(self, wert):
self.wert = wert
Man leitet von bereits bestehenden Klassen neue Klassen ab, um diese um zustätzliche Funktionalitä zu erweitern.
Dabei übernimmt die abgeleitete Klasse alle Fähigkeiten von ihrer Basisklasse, sodass sie zunächst
eine Kopie dieser Klasse ist. Man sagt, die Basisklasse vererbt ihre Fähigkeiten an eine Tochterklasse.
Um eine Klasse von einer anderen erben zu lassen, schreibt ma bei der Definition der Tochterklasse die
Basisklasse in Klammern hinter den Klassennamen.
Beispiel:
class A:
pass
class B(A):
pass
Generell spricht man vom Überschreiben einer Methode, wenn eine Klasse eine Methode neu implementiert,
die sie bereits von ihrer Basisklasse geerbt hat.
Es ist möglich, überschriebene Methoden der Basisklasse explizit aufzurufen, dies gilt auch für den Konstruktor.
Beispiel: super().__init__()
Die Mehrfachvererbung beschreibt das Konzept, bei dem eine Klasse von mehreren Basisklassen erbt.
Beispiel:
class NeueKlasse(Basisklasse1, Basisklasse2, Basisklasse3):
# Definition von Methoden und Attributen
pass
Ein Konzept der objektorientierten Programmierung, um den Zugriff auf Attribute zu steuern, stellen die Setter-
und Getter-Methoden dar. Anstatt direkt auf das Attribut zuzugreifen, wird der Zugriff dabei über spezielle Methoden geregelt.
Python bietet keinen technischen Schutz davor, dass Attribute ohne den Einsatz von Setter- und Getter-Methoden direkt verwendet werden.
Attribute, die nicht von außen direkt aufgerufen werden sollten, sollten mit einem Unterstrich beginnend benannt werden (z.B. _X).
Es ist eine Konvention unter Python-Entwicklern, Attribute und Methoden, die mit einem Unterstrich beginnen, nach Möglichkeit nicht von
außen zu verwenden.
Die explizite Verwaltung von Attributen mittels Setter- und Getter-Methoden ist unschön. Die sogenannten Property-Attribute lösen
dieses Problem, indem Setter- und Getter-Methoden beim Schreiben bzw. Lesen eins Attributs implizit aufgerufen werden.
Für den Parameter fget wird eine Referenz auf eine Getter-Methode für das neue Attribut erwartet. Der Parameter fset gibt die
dazugehörige Setter-Methode an. Mit dem Parameter fdel kann zusätzlich eine Methode angegeben werden, die dann ausgeführt werden soll,
wenn das Attribut per del gelöscht wird. Übr den Parameter doc kann das Attribut mit einem sogenannten Docstring versehen werden.
Methoden und Attribute, die sich immer auf konkrete Instanzen beziehen, werden als nicht-statisch bezeichnet. Dem stehen die
statischen Methoden und Attribute gegenüber, die sich alle Instanzen einer Klasse teilen.
Zur Definition einer statischen Methode dient die Built-in Function staticmethod.
Beispiel:
def m():
print("Hallo statische Methode!")
class A:
m.staticmethod(m)
Eine statische Methode wird zunächst wie eine normale Funktion definiert und erst durch die Funktion staticmethod als statische
Methode an eine Klasse gebunden. Da eine statische Methode sich nicht auf eine Instanz der Klasse bezieht, benötigt sie keinen self-Parameter.
Außerdem kann sie direkt von der Klase aus gerufen werden, ohne dass zuvor eine Instanz erzeugt werden muss. In Python werden statische
Methoden häufig dazu genutzt, alternative Konrtuktoren anzubieten.
Einen solchen alternativen Konstruktor bezeichnet man auch als Factory-Function.