Zum Hauptinhalt springen

(Dynamische) Polymorphie

Unter (dynamischer) Polymorphie (griechisch für Vielgestaltigkeit) versteht man, dass eine Referenzvariable zur Laufzeit durch Typumwandlung Referenzen auf Objekte unterschiedlicher Klassen besitzen kann und dass dadurch unterschiedliche Methodenimplementierungen aufgerufen werden können. Man spricht in diesem Zusammenhang auch vom statischen Datentyp einer Referenzvariablen (der zur Designzeit festgelegt wird) und vom dynamischen Datentyp einer Referenzvariablen (der zur Laufzeit zugewiesen wird). Der statische Typ legt fest, welche Methoden aufgerufen werden können, der dynamische, welche Methodenimplementierung aufgerufen wird. Die Typumwandlung von der abgeleiteten Unterklasse zur Oberklasse bezeichnet man als Upcast, die Rückumwandlung als Downcast.

Computer.java (Auszug)
public class Computer {
...
public ArrayList<String> getSpecification() {
ArrayList<String> specification = new ArrayList<>();
specification.add("description: " + description);
specification.add("cpu: " + cpu);
specification.add("memoryInGb: " + memoryInGb);
return specification;
}
...
}
Hinweis

Im Gegensatz zum Upcast muss bei einem Downcast der Typ explizit angegeben werden. Der Downcast einer nicht zuweisungskompatiblen Referenz führt zu einer ClassCastException.

Der instanceof-Operator

Mit dem Operator instanceof kann zur Laufzeit geprüft werden, ob eine Objektreferenz zuweisungskompatibel zu einer Klasse ist. Eine Objektreferenz ist dann zuweisungskompatibel zu einer Klasse, wenn die Klasse des referenzierten Objektes in einer Vererbungsbeziehung zur Klasse steht. Seit Java 16 ermöglicht der Mustervergleich bei instanceof das Vermeiden notwendiger Typumwandlungen und sorgt gleichzeitig für eine sicherere Programmierung.

MainClass.java (Auszug)
public class MainClass {

public static void main(String[] args) {
...
for (Computer c : computers) {
/* bis Java 16 */
if (c instanceof Notebook) {
Notebook notebook = (Notebook) c; // Downcast
System.out.println(notebook.getScreenSizeInInches());
}
/* seit Java 16 */
if (c instanceof Notebook notebook) { // Downcast
System.out.println(notebook.getScreenSizeInInches());
}
}
...
}

}