Vererbung¶
Die Vererbung in Python ist einfacher und flexibler als die Vererbung in kompilierten Sprachen wie Java und C++, da die dynamische Natur von Python der Sprache nicht so viele Einschränkungen auferlegt.
Um zu sehen, wie Vererbung in Python verwendet wird, beginnen wir mit den
Klassen Square
und Circle
, die wir früher bereits besprochen haben, und
verallgemeinern sie.
Wenn wir diese Klassen nun in einem Zeichenprogramm verwenden wollen, müssen wir
definieren, wo auf der Zeichenfläche sich eine Instanz befindet soll. Wir können
dies tun, indem wir x
- und y
-Koordinaten für jede Instanz definieren:
1>>> class Square:
2... def __init__(self, length=1, x=0, y=0):
3... self.length = length
4... self.x = x
5... self.y = y
6...
7>>> class Circle:
8... def __init__(self, diameter=1, x=0, y=0):
9... self.diameter = diameter
10... self.x = x
11... self.y = y
Dieser Ansatz funktioniert, führt aber zu einer Menge sich wiederholenden Codes,
wenn ihr die Anzahl der Form-Klassen erhöht, da ihr vermutlich wollt, dass jede
Form diese Positionsangabe hat. Dies ist eine Standardsituation für die
Verwendung von Vererbung in objektorientierten Sprachen. Anstatt die x
- und
y
-Variablen in jeder Form-Klasse zu definieren, könnt ihr sie in eine
allgemeine Form-Klasse abstrahieren und jede Klasse, die eine bestimmte Form
definiert, von dieser allgemeinen Klasse erben lassen. In Python sieht diese
Technik wie folgt aus:
1>>> class Form:
2... def __init__(self, x=0, y=0):
3... self.x = x
4... self.y = y
5...
6>>> class Square(Form):
7... def __init__(self, length=1, x=0, y=0):
8... super().__init__(x, y)
9... self.length = length
10...
11>>> class Circle(Form):
12... def __init__(self, diameter=1, x=0, y=0):
13... super().__init__(x, y)
14... self.diameter = diameter
- Zeilen 6 und 11
Square
undCircle
erben von derForm
-Klasse.- Zeilen 8 und 13
rufen die
__init__
-Methode derForm
-Klasse auf.
Es gibt im Allgemeinen zwei Anforderungen bei der Verwendung einer geerbten
Klasse in Python, die ihr beide im Code der Klassen Circle
und Square
sehen könnt:
Die erste Anforderung besteht darin, die Vererbungshierarchie zu definieren, was ihr tut, indem ihr die Klassen, von denen geerbt wird, in Klammern unmittelbar nach dem Namen der Klasse angebt, die mit dem Schlüsselwort
class
definiert wird:Circle
undSquare
erben beide vonForm
.Das zweite Element ist der explizite Aufruf der
__init__
-Methode der geerbten Klasse. Dies erfolgt in Python nicht automatisch, sondern meist über diesuper
-Funktion, genauer durch die Zeilensuper().__init__(x,y)
. Dieser Code ruft die Initialisierungsfunktion vonForm
mit der zu initialisierenden Instanz und den entsprechenden Argumenten auf. Andernfalls würden für die Instanzen vonCircle
undSquare
die Instanzvariablenx
undy
nicht gesetzt.
Die Vererbung kommt auch dann zum Tragen, wenn ihr versucht, eine Methode zu
verwenden, die nicht in den Basisklassen, sondern in der Superklasse definiert
ist. Um diesen Effekt zu sehen, definiert eine weitere Methode in der Klasse
Form
mit dem Namen move
, die eine Form in den x
- und
y
-Koordinaten verschiebt. Die Definition für Form
lautet nun:
1>>> class Form:
2... def __init__(self, x=0, y=0):
3... self.x = x
4... self.y = y
5... def move(self, delta_x, delta_y):
6... self.x = self.x + delta_x
7... self.y = self.y + delta_y
Wenn ihr die Parameter delta_x
und delta_y
der Methode move
in den
__init__
-Methoden von Circle
und Square
übernehmt, könnt ihr z.B. folgende interaktive Sitzung ausführen:
>>> c = Circle(3)
>>> c.move(4, 5)
>>> c.x
4
>>> c.y
5
Die Klasse Circle
im Beispiel hat nicht direkt eine move
-Methode in sich
selbst definiert, aber da sie von einer Klasse erbt, die move
implementiert,
können alle Instanzen von Circle
die move
-Methode verwenden. In
OOP-Begriffen könnte man sagen, dass alle Python-Methoden virtuell sind – d.h., wenn eine Methode in der aktuellen Klasse nicht existiert,
wird die Liste der Oberklassen nach der Methode durchsucht und die erste
gefundene verwendet.