Skip to content

Vererbung

Objektorientiertes Programmieren

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.

python
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:

python
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.

python
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.

python
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 neu definiert, so wird die Methode von Animal aufgerufen:

python
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 und Teacher
  • Student und Teacher 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

python
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
python
class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def sayName(self):
        print(self.name)
python
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)
python
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)
python
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)

Gymnasium Kirchenfeld, fts & lem