Klassen Typ und Intitialisierungs-Klasse, wer bestimmt was?

HansD

Mitglied
Die Frage erscheint vermutlich Fortgeschrittenen lächerlich; aber ich habe in dem Punkt zur Zeit einen Knoten im Gehirn.

  • In welchem Maße entscheiden Initialisierungsklasse und Deklarationstyp über den Zugriff auf Methoden?

  • Schränkt eine Typangabe bei der Deklaration den Zugriff auf Methoden immer ein?

Das Beispiel, das mich zu Zweifeln in diesen Punkten gebracht hat, sieht wie folgt aus:

Java:
class X {
  public void mX() {
    System.out.println("Xm1 ");
  }
}
class Y extends X {
  public void mX() {
    System.out.println("Xm2 ");
  }
  public void mY() {
    System.out.println("Ym");
  }
}
public class Test {
  public static void main(String[] args) {
    X xRef = new Y();
    Y yRef = (Y) xRef;
    yRef.mY();
    xRef.mX();
  }
}

Wenn ich das momentan richtig verstehe, ist der beherrschende Faktor, dass eine Instanz von Y erzeugt wird, und deswegen wird immer auf die Methode mX von Y zugegriffen, welche die signatur-gleiche Methoden von Klasse X außer Kraft setzt (overrrides aka überschreibt).

Zudem wird der Zugriff auf die Methode mY nicht dadurch verhindert, dass die Referenzvariable xRef mit dem Typ der Oberklasse X deklariert wurde, die kein Methode namens mY kennt.
 
Zudem wird der Zugriff auf die Methode mY nicht dadurch verhindert, dass die Referenzvariable xRef mit dem Typ der Oberklasse X deklariert wurde, die kein Methode namens mY kennt.
Das hört sich für mich nicht korrekt an. Auf xRef kannst Du nicht mY() aufrufen, denn xRef ist vom Typ X und da gibt es diese Methode nicht.

Erst durch den Cast hin zu Y in Zeile 17 bist Du in der Lage, mY() aufzurufen. Wäre die Instanz in xRef aber nicht vom Typ Y, dann würdest Du an der Stelle eine Exception bekommen.

Also welche Methoden aufgerufen werden können wird durch den bekannten Typ festgelegt (Also den Typ der Variable wenn man auf einer Variablen den Aufruf durchführt).
Welche konkrete Methode ausgeführt wird, hängt dann aber von der Instanz ab. Das nennt sich Late Binding.

Das Ganze wird aber auch noch etwas komplexer. Man erkennt es schon etwas an der Wortwahl: Es hängt von der Instanz ab. Aber es gibt ja auch statische Methoden (Klassenmethoden) - da hat man ja keine Instanz. Das ist ein Beispiel für Early Binding (Gegenstück zu dem Late Binding). Aber das ist nur ein Fall von mehreren.

Daher noch ein Versuch, es deutlich zu machen:
Early Binding: Schon zur Compilezeit steht fest, welche Methode aufgerufen wird. Zur Laufzeit gibt es da keine Auswahl mehr.
Late Binding: Erst zur Laufzeit wird festgelegt, welche Methode aufgerufen wird.

Generell gilt: Dieses Late Binding findet nur da statt, wo ein Überschreiben möglich ist. Bei Methoden, die nicht überschrieben werden können, kann der Compiler direkt festlegen, was ausgeführt wird. Dies sind:
  • Klassenmethoden
  • private Methoden
  • final Methoden
 

Zurück
Oben