Polymorphie
| 🚧 | Diese Seite befindet sich in Bearbeitung | 🚧 |
| 🤓 | Diese Seite ist eine Bewertungsrichtlinie, die ab Blatt 2 annotiert und ab Blatt 3 abgezogen wird. | 🤓 |
Beschreibung
Wenn wir von Polymorphie reden, sprechen wir vor allem von der Vererbung von Klassen und Methoden – also einem Kernbestandteil der objektorientierten Programmierung.
Durch das Vererben von Eigenschaften an sogenannte "Kindklassen" verringern wir den Anteil an Code, den wir ansonsten mehrfach schreiben müssten. Außerdem ermöglicht uns dieses Vorgehen, verschiedene Eigenschaften ähnlicher Objekte schnell und unabhängig zu modellieren.
Gerne wird bei Polymorphie in der objektorientierten Programmierung auf die Polymorphie in der Biologie verwiesen, da diese einem sehr ähnlichen, wenn nicht sogar gleichen Konzept folgt. Wir geben ein klassisches Beispiel:
abstract class Animal {
void breathe() { /* [...] */ }
abstract void speak();
}
class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow");
}
public void purr() { /* [...] */ }
}
class Dog extends Animal {
@Override
public void speak() {
System.out.println("Bark");
}
public void fetch() { /* [...] */ }
}
Übertragen wir dieses Beispiel in einen biologischen Zusammenhang:
Katzen und Hunde sind beides Tiere und teilen somit grundlegende Eigenschaften. Alle Tiere können atmen und kommunizieren. Allerdings kommunizieren Hunde und Katzen auf unterschiedliche Weise – das zeigt sich in der Methode `speak()`, die in beiden Klassen unterschiedlich implementiert ist. Darüber hinaus besitzen sie individuelle Fähigkeiten: Hunde bringen gerne Stöcke zurück, während Katzen schnurren.Die Polymorphie entsteht hier dadurch, dass wir verschiedene spezialisierte Klassen (Kindklassen) haben, die gemeinsame Methoden aus der Oberklasse (Parentklasse) erben, diese aber jeweils unterschiedlich umsetzen. So können wir mit einem gemeinsamen Oberbegriff ("Animal") unterschiedliche Objekte beschreiben und trotzdem spezifisches Verhalten modellieren.
Warum dieser ganze Aufwand? Könnte man nicht einfach prüfen, welche Klasse ein Objekt hat, und entsprechend reagieren ... oder?
Schauen wir uns das mal in einem konkreten, überzeugenden Beispiel an:
Negativbeispiel:
class Cat{
public void purr() {}
}
class Dog{
public void fetch() {}
}
class Main {
public static void main(String[] args) {
Dog dog = new Dog();
speak(dog);
Cat cat = new Cat();
speak(cat);
}
public static void speak(Object animal) {
if (animal instanceof Cat) {
System.out.println("Cat has spoken");
} else if (animal instanceof Dog) {
System.out.println("Dog has spoken");
} else {
System.out.println("I don't know how that animal speaks");
}
}
}
Positivbeispiel:
abstract class Animal {
abstract void speak();
}
class Cat extends Animal {
@Override
public void speak() {}
public void purr() {}
}
class Dog extends Animal {
@Override
public void speak() {}
public void fetch() {}
}
class Main {
public static void main(String[] args) {
Animal[] animals = {new Dog(), new Cat()};
for (Animal animal : animals) {
animal.speak();
}
}
}
animal.speak() kann hier keinen Fehler erzeugen, da die Methode in allen Klassen entsprechend definiert ist.