So sorgt Java Polymorphie für besseren Code und mehr Möglichkeiten
Polymorphie ist das Herzstück jeder objektorientierten Sprache.
Nicht nur in Java – auch in Python, Javascript und in anderen Sprachen.
Aber was bedeutet Polymorphie eigentlich?
Polymorphie oder auch Polymorphismus genannt, kommt aus dem Griechischen.
Es bedeutet Vielgestaltigkeit.
Etwas freier übersetzt, kannst du es auch als Facettenreichtum bezeichnen.
Im Grunde genommen zielt die ganze Java Vererbung darauf ab, dass du doppelten Code vermeiden kannst.
Und dies hat dann zum Vorteil, dass du deinen Code besser warten und erweitern kannst.
Und Polymorphie setzt dem Ganzen die Krone auf.
Denn durch dieses Feature wird dein Code extrem flexibel.
Doch…
Am besten ich zeige es dir an einem Beispiel.
Inhalt
Java Polymorphie am Beispiel einer Figurenklasse.
Ich habe einmal drei Klassen angelegt.
Eine Superklasse namens Figur.
public class Figur {
String farbe;//Farbe der Figur
void info(){
System.out.println("Die Figur ist "+farbe);
}
}
Und die Unterklassen „Viereck“ und „Dreieck“ erweitern diese.
public class Viereck extends Figur{
int laengeA;//Länge der Seite A
int laengeB;//Länge der Seite B
void berechneFlaeche(){
System.out.println("Fläche vom Viereck");
}
}
public class Dreieck extends Figur{
void berechneFlaeche(){
System.out.println("Fläche vom Dreieck");
}
}
So kannst du dir dies grafisch vorstellen:
Dazu noch eine Programmstart-Klasse mit main-Methode.
In dieser habe ich bereits drei Objekte erstellt.
public class ProgrammStart {
public static void main(String[] args) {
Figur figurEins = new Figur(); //Figuren-Objekt
Viereck vierEins = new Viereck();//Objekt der Klasse Viereck
Dreieck dreiEins = new Dreieck();//Objekt der Klasse Dreieck
}
}
- Das Objekt „figurEins“ stammt aus der Superklasse.
Somit kann die Referenzvariable auf Methoden und Variablen der Klasse „Figur“ zugreifen. - Die Eigenschaften und Methoden der Unterklassen „Viereck“ und „Dreieck“ stehen nicht zur Verfügung.
Hier die Punktnotation zum Figuren-Objekt:
- Das Dreieck kann mehr.
- Es vereint die Eigenschaften und Methoden der Figurenklasse und der Dreiecksklasse.
Hier ist das Bild dazu:
- Das Viereck hat noch mehr Eigenschaften bzw. Variablen.
- Denn auch das Viereck hat neben den Eigenschaften der Figurenklasse, ebenfalls die Eigenschaften der Vierecksklasse.
Dieses Bild macht auch dies deutlich:
Okay…
Bis jetzt ist dies ganz normale Java Vererbung.
Polymorphie geht noch einen Schritt weiter.
Doch lass uns erst einmal einen Schritt zurück.
Schauen wir uns das Objekte-Erstellen mal näher an.
Die Erstellung des Objektes erfolgt in mehreren Schritten.
- Es wird ein Speicherplatz reserviert.
Die Größe entspricht dem Datentypen – Figur, Dreieck oder Viereck. - Der Verweis auf diesen Speicherplatz wird in einer Variable gespeichert.
Zum Beispiel: figurEins, vierEins oder dreiEins (Siehe unser Beispiel) - Mit dem Konstruktoraufruf wird dann ein tatsächliches Objekt aus der Klasse Figur, Dreieck oder Viereck angelegt.
Du kannst sagen:
- Alles was links neben dem Zuweisungsoperator (Gleichheitszeichen) steht, dient als Verweis auf den Speicher (Heap).
- Und alles was rechts neben dem Zuweisungsoperator steht, dient der Objekt-Erstelllung.
In unserem Beispiel zeigen somit drei Referenzvariablen – auf drei unterschiedliche Objekte im Speicher.
So weit – so gut.
Jetzt erstell ich einmal ein neues Dreieck, aber nicht vom Datentyp Dreieck – sondern vom Datentyp Figur.
public class ProgrammStart {
public static void main(String[] args) {
Figur figurEins = new Figur(); //Figuren-Objekt
Viereck vierEins = new Viereck();//Objekt der Klasse Viereck
Dreieck dreiEins = new Dreieck();//Objekt der Klasse Dreieck
Figur dreieckZwei = new Dreieck();//neues Dreieck vom Datentyp Figur
}
}
Du siehst: Es erscheint keine Fehlermeldung.
Trotz strenger Typisierung lässt es Java zu, dass du für ein Dreieck – einen fremden Datentypen – reserviert.
Die Datentypen Dreieck und Figur scheinen kompatibel zu sein.
Was steckt jetzt drin- ein Dreieck oder eine Figur?
Es handelt sich hierbei immer noch um ein vollwertiges Dreieck.
Du kannst somit ein Objekt vielfältig anbieten.
Dies ist Polymorphie.
Aber wie weit geht das Ganze?
Das Substitutionsgesetz der Java Polymorphie
Beachte…
Java ist streng typisiert.
Diese Polymorphie funktioniert nur bei höheren bzw. komplexen Datentypen, wie Objekten.
Mit einen Integer oder Boolean funktioniert das nicht.
Substitution bedeutet „Ersetzen“.
Du kannst also einen komplexen Datentyp durch einen anderen ebenfalls komplexen Datentyp ersetzen.
Aber nur bei Datentypen, welche sich in der gleichen Vererbungslinie befinden.
Das Dreieck oder das Viereck sind beides Figuren.
Sie sind somit Spezialfälle der Superklasse „Figur“.
Durch Polymorphie werden die Eigenschaften der Objekte versteckt.
Versteckt ist vielleicht nicht der richtige Ausdruck.
Viel besser ist es zu sagen:
„Die Objekte schützen ihre Eigenschaften nach außen.“
Denn jetzt ist es so, dass du nicht mehr auf die spezialisierten Eigenschaften der Dreiecksklasse zugreifen kannst.
Du kannst weder die Instanzmethoden aufrufen, noch den Instanzvariablen – Werte zuweisen.
Das Objekt verbirgt den Zugriff nach außen.
Und die andere Richtung?
Ist es möglich eine Figur vom Datentyp Dreieck anzulegen?
Andersrum funktioniert es nicht.
Du kannst keine Figur anlegen, welche du dann in ein Dreieck oder Viereck steckst.
Denn lies den Code einmal von rechts nach links.
- Ist jedes Dreieck eine Figur? – Ja
- Und ist jedes Viereck eine Figur? – Auch ja
Aber:
- Ist jede Figur ein Dreieck? – Nein
- Und ist jede Figur ein Viereck- ebenfalls nein
Man kann sagen:
Es gibt neben Dreiecke noch andere Figuren.
Der Datentyp Figur ist somit viel weitreichender als ein Dreieck.
Und deshalb passt zwar ein Dreieck in den Figur-Datentypen.
Aber umgedreht funktioniert es nicht.
Formal gesagt, bedeutet Substitution:
„Du kannst ein Objekt erzeugen und diesem Objekt einen anderen Datentypen zuweisen.
Aber dieser andere Datentyp muss in der selben Vererbungslinie und mindestens eine Stufe höher, als das erzeugte Objekt sein.“
Du kannst die Zuordnung auch noch später vollziehen.
Beispielsweise so:
public class ProgrammStart {
public static void main(String[] args) {
Figur figurEins = new Figur(); //Figuren-Objekt
Viereck vierEins = new Viereck();//Objekt der Klasse Viereck
Dreieck dreiEins = new Dreieck();//Objekt der Klasse Dreieck
dreiEins.farbe="Gelb";//Dreieck ist jetzt gelb
figurEins=dreiEins;//Figur-Objekt wird zerstört. Die Ref.-Variable zeigt auf das Dreieck.
figurEins.info();//Bildschirmausgabe zur Kontrolle = Gelbes Dreieck
}
}
Probiere den Code einmal aus.
Aufgrund des Umswitchens der Referenzvariablen wird das Figuren-Objekt aufgegeben und zerstört.
Wenn du dann mittels Punktnotation auf die „Figuren-Referenzvariable“ zugreifst, landest du immer beim Dreieck.
Was bewirkt diese Java Polymorphie? Welchen Vorteil bringt Polymorphismus
Was müsstest du tun, wenn du alle Figuren vergrößern möchtest?
Da Java streng typisiert ist, musst du ohne Polymorphie für sämtliche Figurentypen Extra-Methoden anlegen.
Und diesen Methoden kannst du dann einen Parameter vom Typ „Dreieck“ oder „Viereck“ übergeben.
Sobald du neue Figurentypen in dein Programm implementierst, brauchst du neue Methoden – zum Beispiel für Kreise.
Durch die Java Polymorphie kannst du jetzt eine Methode anbieten und ihr den abstrakten Datentyp „Figur“ übergeben.
Du musst diese Methode auch nie wieder abändern. Denn der Polymorphismus bewirkt, dass später auch Kreise verarbeitet werden können.
Oder Arrays.
Ohne Polymorphie kannst du lediglich Objekte vom selben Datentypen in einem Array speichern.
Mit Polymorphie kannst du sämtliche Objekte der selben Vererbungslinie in dieses Array stecken.
Die Vorteile von Polymorphie sind:
- Der Code ist besser zu warten.
- Dein Java Code ist leichter zu erweitern.
- Die Objekte verstecken nach außen ihre Methoden und Eigenschaften.
Dadurch werden diese besser geschützt. - Du bist bei der Programmierung sehr viel flexibler.
Zusammenfassung:
- Polymorphie bewirkt, dass du ein Objekt anlegen und dabei abstraktere Datentypen verwenden kannst.
- Dadurch erreichst du, dass dein Code besser wartbar, leichter erweiterbar und flexibler ist.
- Die Java Polymorphie geht dabei nur in eine Richtung.
Du kannst lediglich Datentypen verwenden, welche in der Vererbungslinie hierarchisch weiter oben stehen. (Superklassen)