Mehrfachvererbung

Objekt: Toyota Primus Hybrid

Bildquelle

Gewicht: 1,6 Tonnen

Leistung: 122 PS

Farbe: blaugrau

Geschwindigkeit: 0 km/h

Sitzplätze: 5

Wir betrachten das Objekt Toyota Primus Hybrid. Dieses Objekt besitzt sowohl einen Verbrennungs- als auch einen Elektroantrieb. Man kann in somit der Klasse Verbrenner-PKW und Elektro-PKW zuordnen. Man könnte also eine Klasse bilden, die die Eigenschaften beider Klassen erbt. Dieses Vorgehen nennt man Mehrfachvererbung. Wir nennen die neue Klasse Hybrid. Die folgende Grafik zeigt die Klasse im UML-Diagramm:

In unserem Fall müssen für die neue Klasse keine zusätzlichen Attribute gebildet werden. Theoretisch wäre das aber möglich.

In unserem Fall haben die beiden Klassen von denen geerbt wurde eine gemeinsame Elternklasse. Das muss aber nicht so sein.

Umsetzung in Python

# Definition einer Klasse PKW class PKW: # Attribute der Klasse bezeichnung="" leistung=0 farbe="" geschwindigkeit=0 sitzplaetze=0 # Methoden der Klasse def __init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze): # Konstruktor self.bezeichnung = bezeichnung self.leistung = leistung self.farbe = farbe self.geschwindigkeit = geschwindigkeit self.sitzplaetze def geschwindigkeitAendern(self, wert): self.geschwindigkeit += wert return self.geschwindigkeit def lackieren(self, farbe): self.farbe = farbe def ausgabe(self): print("PKW") print("Bezeichnung:",self.bezeichnung) print("Leistung:", self.leistung,"PS") print("Farbe:", self.farbe) print("Geschwindigkeit:", self.geschwindigkeit,"km/h") print("Sitzplätze",self.sitzplaetze) # Definition der abgeleiteten Klassen class VerbrennerPKW(PKW): # zusätzliches Attribut der Klasse tankinhalt = 0 def __init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, tankinhalt): # Konstruktor # zunächst wird er Konstruktor der Elternklasse aufgerufen PKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze) # dann wird noch das letzte Attribut zugewiesen self.tankinhalt=tankinhalt def ausgabe(self): PKW.ausgabe(self) print("Tankinhalt:",self.tankinhalt,"l") def tanken(self,wert): self.tankinhalt += wert class ElektroPKW(PKW): # zusätzliches Attribut der Klasse ladezustand = 0 def __init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, ladezustand): # Konstruktor # zunächst wird er Konstruktor der Elternklasse aufgerufen PKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze) # dann wird noch das letzte Attribut zugewiesen self.ladezustand=ladezustand def ausgabe(self): PKW.ausgabe(self) print("Ladezustand:",self.ladezustand,"%") def laden(self,ladezustand): self.ladezustand += wert class Hybrid(VerbrennerPKW, ElektroPKW): def __init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, ladezustand, tankinhalt): # Konstruktor # Man ruft einfach beide Konstruktoren der Elternklasse auf ElektroPKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, ladezustand) VerbrennerPKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, tankinhalt) def ausgabe(self): ElektroPKW.ausgabe(self) print("Tankinhalt:",self.tankinhalt,"l") # Hauptprogramm # Instanzen der Klassen werden erzeugt ford = VerbrennerPKW("Ford Focus",150,"weiß",30, 5, 50) tesla = ElektroPKW("Tesla Roadster",306,"blau",0, 2, 100) toyota = Hybrid("Toyota Primus",120,"blaugrau",0,5,40,80) # Für die Objekte wird die Methode ausgabe() ausgeführt ford.ausgabe() print() tesla.ausgabe() print() toyota.ausgabe()

Der Quelltext aus dem Abschnitt Vererbung wurde um die Klasse Hybrid ergänzt. In der Klassendefinition class Hybrid(VerbrennerPKW, ElektroPKW) erscheinen beide Elternklassen. Im Konstruktor:

def __init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, ladezustand, tankinhalt): # Konstruktor # Man ruft einfach beide Konstruktoren der Elternklasse auf ElektroPKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, ladezustand) VerbrennerPKW.__init__(self, bezeichnung, leistung, farbe, geschwindigkeit, sitzplaetze, tankinhalt)

werden beide Konstruktoren der Elternklassen aufgerufen. Alternativ kann man auch einen Konstruktor aufrufen und das fehlende Attribut im Konstruktor definieren.

Auch bei der ausgabe() wird die entsprechende Methode einer Elternklasse aufgerufen und die entsprechende print-Anweisung ergänzt.

Erklärvideo

Aufgaben

Aufgabe 1

Teste das Beispiel aus dem Video!

Aufgabe 2

Ergänze die Aufgabe 2 aus dem Abschnitt Vererbung um eine Klasse Uniklinik (Siehe UML-Diagramm) !

Schreibe für die neue Klasse die Methoden __init__ und __str__ und teste die Klasse an Beispielen.