Bei der Vererbung (inheritance) können Methoden und Eigenschaften einer Klasse weitergegeben werden.
Definition: Vererbung
Mittels Vererbung kann eine neue Klasse aufbauend auf einer existierenden Klasse geschaffen werden. Die Beziehung zwischen neuer und bestehender Klasse ist dauerhaft.
Die neue Klasse kann dabei eine Erweiterung (Spezialisierung) oder eine Einschränkung (Generalisierung) der ursprünglichen Klasse sein.
Z.B. könnte die Klasse Sheep
von Animal
erben, weil das Schaf ja auch alle Eigenschaften eines Tieres hat. Die Klasse Sheep
kann dann weitere «Schaf-spezifische» Dinge erledigen. Nun könnte man weitere Tier-Unterklassen hinzufügen, z.B. eine Klasse Dog
die ebenfalls von der Oberklasse Animal
erbt.
class Animal():
pass
class Sheep(Animal):
pass
class Dog(Animal):
pass
- Zeile 4 & 7
- Es werden Unterklassen der Klasse
Animal
erstellt
Polymorphie (polymorphism)
Der Begriff «Polymorphismus» kommt aus dem Griechischen und steht für «Vielgestaltigkeit».
Definition: Polymorphie
Mittels Vererbung ist es möglich, dass ein Objekt «vielgestaltig» ist: Eine Unterklasse kann Methoden der Oberklasse überschreiben. Zur Laufzeit wird dann entschieden, welche Methode ausgeführt wird.
Z.B. hat der Plus-Operator +
in Python mehrere Gestalten – je nachdem ob wir zwei Zahlen addieren oder zwei Strings zusammenhängen:
print(4 + 3)
print("Hallo" + " du!")
bei Klassen
In Python können wir verschiedene Objekte in eine Liste packen. Die Objekte der Klassen Sheep
und Dog
haben beide eine gleich benannte Methode makeSound
. Wir können nun in einer Liste Objekte von Sheep
und Dog
durchgehen und die Methode aufrufen. Dabei wird natürlich die jeweilig zum Objekt gehörende Methode ausgeführt.
class Sheep():
def makeSound(self):
print("mähhh")
class Dog():
def makeSound(self):
print("wuff")
shaun = Sheep()
bitzer = Dog()
animals = [shaun, bitzer]
for animal in animals:
animal.makeSound()
mit Vererbung
Besser ist es, wenn wir eine Oberklasse Animal
definieren. Somit stellen wir sicher, dass die Methode makeSound
definiert ist. Sheep
und Dog
erben dann von Animal
und können die Methode makeSound
überschreiben, also neu definieren.
class Animal():
def makeSound(self):
pass
class Sheep(Animal):
def makeSound(self):
print("mähhh")
class Dog(Animal):
def makeSound(self):
print("wuff")
shaun = Sheep()
bitzer = Dog()
animals = [shaun, bitzer]
for animal in animals:
animal.makeSound()
Wenn die Unterklasse eine Methode nicht überschreibt – also nicht neu definiert, so wird die Methode von Animal
aufgerufen:
class Animal():
def makeSound(self):
print("Tierlaut")
class Dog(Animal):
pass
shaun = Sheep()
shaun.makeSound()
Aufgabe: Harry Potter
Schau dir das folgende Klassen-Diagramm an:
Versuche dieses mit Python zu implementieren:
- 3 Klassen
Person
,Student
undTeacher
Student
undTeacher
erben vonPerson
- im mittleren Bereich stehen die Eigenschaften und der dazugehörige Datentyp
- im letzten Abschnitt sind die Methoden aufgeführt
Teste deine Klassen mit dem folgenden Python-Skript
from student import Student
from teacher import Teacher
snape = Teacher("Severus Snape", 32)
harry = Student("Harry Potter", 11)
hermione = Student("Hermione Granger", 11)
snape.addStudent(harry)
snape.addStudent(hermione)
harry.grades = [5, 4.5, 3]
hermione.grades = [6, 6, 6]
for student in snape.listOfStudents:
student.sayName()
print(student.getAverage())
Lösung: Harry Potter
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def sayName(self):
print(self.name)
from person import Person
class Student(Person):
def __init__(self, name, age):
super().__init__(name, age)
self.grades = []
def getAverage(self):
return sum(self.grades)/len(self.grades)
from person import Person
class Teacher(Person):
def __init__(self, name, age):
super().__init__(name, age)
self.listOfStudents = []
def addStudent(self, student):
self.listOfStudents.append(student)
from student import Student
from teacher import Teacher
snape = Teacher("Severus Snape", 32)
harry = Student("Harry Potter", 11)
hermione = Student("Hermione Granger", 11)
snape.addStudent(harry)
snape.addStudent(hermione)
harry.grades = [5, 4.5, 3]
hermione.grades = [6, 6, 6]
for student in snape.listOfStudents:
student.sayName()
print(student.getAverage())
die Unterklassen Student
und Teacher
verwenden den Konstruktor der Oberklasse Person
. Dies wird durch die spezielle Funktion super()
möglich! So können die Eigenschaften name
und age
, welche aller Objekte die von Person
erben — also auch Student
und Teacher
– haben, an den Konstruktor von Person
übergeben werden. Weitere Eigenschaften können dann im Konstruktor der Unterklasse gesetzte werden: So stellt Student
sicher, dass die Liste grades
einen Wert erhält. Teacher
macht das selbe für listOfStudents
.
Zusatzaufgabe
Erweitere das Programm mit deinen Ideen:
- findest du weitere Unterklassen von
Person
? - findest du weitere Beziehungen zwischen den Klassen?
- wie könnte man die Klassen erweitern? (Eigenschaften, Methoden)