======Mehrfachvererbung======
**Objekt:** Toyota Primus Hybrid
{{ :python:obj:toyota-hybrid-cc.jpg?400 |}}
[[https://www.flickr.com/photos/albertma/5477146679/in/photolist-8SfXHV-8Sj8Uu-8SfWLa-8SfZqg-8Sj4eu-8Sj4uJ-8Sj9v7-8SfYmP-8Sj5ww-8SfXEF-9kZN4n-8Sj5sQ-8SfWGt-8Sj9pE-8Sj9m5-dLBDcq-dLw8yM-9m3SNb-wfKz7C-8Sj63Y-wdJHm5-9JWNTu-9kZNTr-9m3T91-9kZNB2-9kZNhn-9kZNbt-9m3StN-dLw8rF-dLw82X-9m3SyL-dLw7E2-9kZNZ6-dLBDU7-9KoAXf-dLBDiW-dLw7L4-dLw7WB-dLw73B-dLw7oe-dLw8cT-dLw7ie-dLw7Ui-dLw78D-dLBCGC-dLBCyW-x4KN29-dLBCvq-2k41yPp-2k42eEM|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:
{{ :python:obj:mehrvererb.png?direct&400 |}}
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=====
{{youtube>s_zUOuGN4lo}}
=====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) !
{{ :python:obj:gebaeude-mehr.png?direct&400 |}}
Schreibe für die neue Klasse die Methoden ''%%__init__%%'' und ''%%__str__%%'' und teste die Klasse an Beispielen.