Inselupdate: Wie wo was dynamisch binden
Es gibt bei Methoden von konkreten Klasse, abstrakte Klassen und Schnittstellen Unterschiede, wo der Aufruf letztendlich landet. Nehmen wir folgende Methode an:
void f( T t ) {
t.m();
}
Fordert die Methode ein Argument vom Typ T und ruft auf dem Parameter t die Methode m() auf, so können wir folgendes festhalten:
-
Ist T eine finale Klasse, so wird immer die Methode
m()von T aufgerufen, da es keine Unterklassen geben kann, diem()überschreiben. -
Ist T eine nicht-finale Klasse und
m()eine finale Methode, wird genaum()aufgerufen, weil kein Unterklassem()überschreiben kann. -
Ist T eine nicht-finale Klasse und
m()keine finale Methode, so könnten Unterklassen von Tm()überschreiben undt.m()würde dann dynamisch die überschriebene Methode aufrufen. -
Ist T eine abstrakte Klasse und
m()eine abstrakte Methode, so wird in jedem Fall eine Realisierung vonm()in einer Unterklasse aufgerufen. -
Ist T eine Schnittstelle, und
m()keine Default-Implementierung, so wird in jedem Fall eine Implementierungm()einer implementierenden Klasse aufgerufen. -
Ist T eine Schnittstelle, und
m()eine Default-Implementierung, so kannt.m()bei der Default-Implementierung landen, oder bei einer überschriebenen Version einer implementierenden Klasse.