1. Was bedeutet Polymorphie? ("Vielgestaltigkeit")
Das Wort Polymorphie stammt aus dem Griechischen:
poly = viel | morphe = Gestalt, Form → "Vielgestaltigkeit".
In der Objektorientierten Programmierung bedeutet das: Verschiedene Klassen besitzen Methoden mit demselben Namen und derselben Signatur, führen die Aufgabe im Hintergrund jedoch auf ihre ganz eigene Art und Weise aus.
Wenn du auf "Power" drückst, sendet die Fernbedienung an alle Geräte den Befehl
einschalten():
- Der Fernseher aktiviert sein OLED-Display.
- Die Soundbar startet den Verstärker und verbindet Bluetooth.
- Die Spielkonsole lädt das Betriebssystem und meldet den Controller an.
Die Fernbedienung muss nicht wissen, wie das Einschalten intern funktioniert – sie weiß nur, dass jedes Gerät eine Methode
einschalten() besitzt!
2. 📊 UML-Klassendiagramm: Formen & Zeichenfläche
In unserem Praxisbeispiel ist Form ein Interface / eine abstrakte Basisklasse.
Rechteck, Kreis und Dreieck implementieren jeweils ihre eigene flaeche() und umfang().
+ {abstract} flaeche() -> float
+ {abstract} umfang() -> float
+ info() -> str
- hoehe: float
+ umfang() -> float
+ info() -> str
+ umfang() -> float
+ info() -> str
- seite_b: float
+ flaeche() -> float
+ umfang() -> float
+ info() -> str
- formen: list[Form]
+ gesamte_flaeche() -> float (ruft form.flaeche() auf)
+ gesamter_umfang() -> float (ruft form.umfang() auf)
+ formen_nach_farbe(farbe) -> list[Form]
+ groesste_form() -> Form | None
+ report() -> list[str]
3. Wie funktioniert Polymorphie in Code?
Der Clou: Schleifen über gemischte Objekte ohne if/else!
Ohne Polymorphie müsstest du für jeden Typ eine eigene if/elif-Weiche schreiben:
# So bitte NICHT programmieren: for form in formen: if isinstance(form, Rechteck): f = form.breite * form.hoehe elif isinstance(form, Kreis): f = 3.14159 * form.radius ** 2 # Bei jeder neuen Form (z.B. Dreieck) muss überall neuer Code eingefügt werden!
Mit Polymorphie rufen wir einfach dieselbe Methode auf allen Objekten auf – Python wählt automatisch die richtige Version:
formen = [ Rechteck(4.0, 5.0), Kreis(3.0), Dreieck(3.0, 4.0) ] # Ein einziger, eleganter Methodenaufruf für alle Formen: for form in formen: print(f"{form.info()} -> Fläche: {form.flaeche():.2f}")
4. Abstrakte Basisklassen (abc.ABC) & Duck Typing
Python ist dynamisch typisiert: Solange ein Objekt eine Methode
flaeche() besitzt, kann es auf der Zeichenflaeche platziert werden.
Verträge erzwingen mit abc.ABC
Um sicherzustellen, dass Entwickler nicht vergessen, wichtige Methoden wie flaeche() zu schreiben, nutzen wir Pythons abc-Modul (Abstract Base Classes):
from abc import ABC, abstractmethod class Form(ABC): def __init__(self, farbe: str = "schwarz"): self.farbe = farbe @abstractmethod def flaeche(self) -> float: pass # Jede Kindklasse MUSS diese Methode überschreiben!
flaeche() nicht implementiert, verhindert Python das Erstellen von Objekten mit einem klaren Fehler:
TypeError: Can't instantiate abstract class MeineForm with abstract method flaeche
5. 🎯 Deine Aufgaben in aufgabe.py
Öffne die Datei aufgabe.py und vervollständige das System:
💡 Lösungshinweise (Aufklappen bei Bedarf)
🔍 Tipp zu TODO 14 (Hypotenuse berechnen)
def hypotenuse(self) -> float: return math.sqrt(self.seite_a ** 2 + self.seite_b ** 2)
🔍 Tipp zu TODO 21 (Polymorphe Gesamtfläche)
def gesamte_flaeche(self) -> float: return sum(form.flaeche() for form in self.formen)
🔍 Tipp zu TODO 23 (Farben filtern ohne Groß-/Kleinschreibung)
def formen_nach_farbe(self, farbe: str) -> list[Form]: return [f for f in self.formen if f.farbe.lower() == farbe.lower()]
6. 🧪 Lösung überprüfen
Führe im Terminal im Ordner 11_polymorphie_und_interfaces folgenden Befehl aus:
python3 test_aufgabe.py