Polymorphie
Polymorphie ist ein OOP-Konzept, bei dem Objekte unterschiedlicher Klassen auf denselben Methodenaufruf unterschiedlich reagieren können.
Auf dieser Seite
Polymorphie (griechisch für “Vielgestaltigkeit”) ist eines der fundamentalen Konzepte der objektorientierten Programmierung (OOP). Sie ermöglicht es, dass Objekte unterschiedlicher Klassen auf denselben Methodenaufruf unterschiedlich reagieren können. Zusammen mit Vererbung und Kapselung bildet Polymorphie die drei Säulen der OOP.
Definition und Grundprinzip
Das Wort Polymorphie stammt aus dem Griechischen und setzt sich aus “poly” (viel) und “morph” (Gestalt) zusammen. In der Programmierung bedeutet dies: Eine Methode kann in verschiedenen Klassen unterschiedlich implementiert sein, obwohl sie denselben Namen und dieselbe Signatur trägt.
Der entscheidende Vorteil: Du kannst Objekte verschiedener Klassen einheitlich behandeln, solange sie eine gemeinsame Schnittstelle oder Oberklasse teilen. Der konkrete Code, der ausgeführt wird, hängt vom tatsächlichen Typ des Objekts zur Laufzeit ab.
Arten der Polymorphie
In der objektorientierten Programmierung unterscheidet man zwei Hauptarten von Polymorphie, die zu unterschiedlichen Zeitpunkten aufgelöst werden:
Statische Polymorphie (Compile-Zeit)
Bei der statischen Polymorphie wird bereits zur Compile-Zeit entschieden, welche Methode aufgerufen wird. Das bekannteste Beispiel ist die Methodenüberladung (Method Overloading): Mehrere Methoden tragen denselben Namen, unterscheiden sich aber in ihrer Parameterliste.
public class Rechner {
// Überladene Methoden mit gleichem Namen
public int addiere(int a, int b) {
return a + b;
}
public double addiere(double a, double b) {
return a + b;
}
public int addiere(int a, int b, int c) {
return a + b + c;
}
}
Der Compiler wählt anhand der übergebenen Argumente die passende Methode aus. Dies geschieht vor der Programmausführung, daher “statisch”.
Dynamische Polymorphie (Laufzeit)
Die dynamische Polymorphie ist das eigentliche Herzstück der OOP. Hier wird erst zur Laufzeit entschieden, welche Methode ausgeführt wird. Sie basiert auf Methodenüberschreibung (Method Overriding): Eine Unterklasse definiert eine Methode der Oberklasse neu.
// Abstrakte Oberklasse
abstract class Tier {
public abstract void gibLaut();
}
// Konkrete Unterklassen
class Hund extends Tier {
@Override
public void gibLaut() {
System.out.println("Wuff!");
}
}
class Katze extends Tier {
@Override
public void gibLaut() {
System.out.println("Miau!");
}
}
// Polymorphe Verwendung
public class Main {
public static void main(String[] args) {
Tier meinTier = new Hund(); // Referenz vom Typ Tier
meinTier.gibLaut(); // Ausgabe: Wuff!
meinTier = new Katze(); // Gleiche Referenz, anderes Objekt
meinTier.gibLaut(); // Ausgabe: Miau!
}
}
Das Schlüsselprinzip: Die Variable meinTier hat den Typ Tier, aber das tatsächliche Verhalten wird durch den konkreten Objekttyp (Hund oder Katze) bestimmt.
Polymorphie mit Interfaces
Neben Vererbung kannst du Polymorphie auch durch Interfaces (Schnittstellen) erreichen. Verschiedene Klassen implementieren dasselbe Interface und können dadurch einheitlich behandelt werden:
// Interface definiert den Vertrag
interface Zeichenbar {
void zeichne();
}
// Verschiedene Klassen implementieren das Interface
class Kreis implements Zeichenbar {
@Override
public void zeichne() {
System.out.println("Zeichne einen Kreis");
}
}
class Rechteck implements Zeichenbar {
@Override
public void zeichne() {
System.out.println("Zeichne ein Rechteck");
}
}
// Polymorphe Verarbeitung
public void alleZeichnen(List<Zeichenbar> formen) {
for (Zeichenbar form : formen) {
form.zeichne(); // Jede Form weiß selbst, wie sie sich zeichnet
}
}
Interfaces sind besonders wertvoll, weil sie Polymorphie ohne Vererbungshierarchie ermöglichen. Eine Klasse kann mehrere Interfaces implementieren und dadurch in verschiedenen polymorphen Kontexten verwendet werden.
Vorteile der Polymorphie
Polymorphie bietet erhebliche Vorteile für die Softwareentwicklung und ist ein Grund, warum objektorientierte Programmierung so verbreitet ist:
- Erweiterbarkeit: Neue Klassen können hinzugefügt werden, ohne bestehenden Code zu ändern
- Wartbarkeit: Änderungen an einer Klasse betreffen nicht den Code, der sie polymorph verwendet
- Wiederverwendbarkeit: Generischer Code funktioniert mit allen kompatiblen Typen
- Lesbarkeit: Einheitliche Schnittstellen machen den Code verständlicher
- Testbarkeit: Mock-Objekte können echte Implementierungen ersetzen
Polymorphie in verschiedenen Programmiersprachen
Das Konzept der Polymorphie existiert in allen objektorientierten Sprachen, wird aber unterschiedlich umgesetzt:
Java
Java verwendet das Schlüsselwort extends für Vererbung und implements für Interfaces. Methoden sind standardmäßig überschreibbar, außer sie sind als final markiert. Die Annotation @Override dokumentiert beabsichtigte Überschreibungen.
C#
In C# müssen Methoden explizit als virtual deklariert werden, um überschreibbar zu sein. Die Überschreibung erfolgt mit dem Schlüsselwort override. Dies macht Polymorphie sichtbarer im Code.
class Tier {
public virtual void GibLaut() {
Console.WriteLine("Tier macht Geräusch");
}
}
class Hund : Tier {
public override void GibLaut() {
Console.WriteLine("Wuff!");
}
}
Python
Python nutzt Duck Typing: “Wenn es wie eine Ente geht und wie eine Ente quakt, ist es eine Ente.” Objekte müssen nicht von derselben Klasse erben. Es genügt, wenn sie die erwarteten Methoden besitzen.
class Hund:
def gib_laut(self):
return "Wuff!"
class Katze:
def gib_laut(self):
return "Miau!"
# Polymorphie durch Duck Typing
def tier_geraeusch(tier):
print(tier.gib_laut())
tier_geraeusch(Hund()) # Wuff!
tier_geraeusch(Katze()) # Miau!
Praxisbeispiel: Plugin-System
Ein klassisches Anwendungsbeispiel für Polymorphie ist ein Plugin-System. Der Hauptcode definiert eine Schnittstelle, und verschiedene Plugins implementieren diese auf ihre eigene Weise:
// Plugin-Interface
interface ExportPlugin {
String getFormat();
void exportiere(Dokument dok);
}
// Konkrete Plugins
class PDFExport implements ExportPlugin {
@Override
public String getFormat() { return "PDF"; }
@Override
public void exportiere(Dokument dok) {
// PDF-spezifische Logik
}
}
class CSVExport implements ExportPlugin {
@Override
public String getFormat() { return "CSV"; }
@Override
public void exportiere(Dokument dok) {
// CSV-spezifische Logik
}
}
// Verwendung - der Code kennt nur das Interface
class Anwendung {
private List<ExportPlugin> plugins = new ArrayList<>();
public void registriere(ExportPlugin plugin) {
plugins.add(plugin);
}
public void exportiereAlle(Dokument dok) {
for (ExportPlugin plugin : plugins) {
plugin.exportiere(dok); // Polymorpher Aufruf
}
}
}
Neue Export-Formate können hinzugefügt werden, ohne den Code der Anwendung zu ändern. Das ist die Stärke von Polymorphie: Offen für Erweiterung, geschlossen für Änderung (Open/Closed-Prinzip).
Polymorphie in der IT-Praxis
Polymorphie ist kein abstraktes Konzept, sondern begegnet dir in nahezu jedem objektorientierten Softwareprojekt. Wer als Fachinformatiker für Anwendungsentwicklung arbeitet, wird Polymorphie täglich einsetzen. Sei es bei der Arbeit mit Frameworks, beim Implementieren von Design Patterns oder beim Testen mit Mock-Objekten.
Quellen und weiterführende Links
Prüfungsbezug
Passt zu deiner Prüfungsvorbereitung
Wenn dir dieser Begriff in Aufgaben, Projektdokumentation oder Fachgespräch begegnet, ordne ihn direkt in den Prüfungsstoff ein.