2014-03-13 10 views
8

Ich habe alle ähnlichen Fragen zur späten Bindung an Stack-Überlauf durchsucht, und ich würde streng mit niemandem übereinstimmen, der diese Frage als ein Duplikat markiert. Als erstes habe ich dieses Beispiel in einer anderen Frage gefunden, aber ich verstehe nicht, wie ich wissen soll, wann etwas während der Kompilierungszeit entschieden wird und wann während der Laufzeit etwas entschieden wird. Im Grunde läuft darauf hinaus der Kern meiner Frage auf zwei Dinge auf:Späte Bindung in Java

  • Was in diesem Beispiel muß bringt mich auf die logische Schlussfolgerung, dass ein Verfahren späte Bindung ist und ein weiterer früher verbindlich

  • Wie weiß ich, dass, wenn die Entscheidung darüber, welche Version eines Verfahrens wird während der Laufzeit oder kompilieren Zeit in Java

Code auszuführen entschieden:

+0

Verspätete Bindung tritt nicht bei 'finalen' 'statischen' oder' privaten' Methoden auf. Für jeden anderen tut es. Das ist alles. – Pshemo

+3

Hinweis für zukünftige Leser: Die Kommentare im obigen Code sind falsch! –

+1

Könnten Sie bitte die Kommentare dann ändern – user3163829

Antwort

2

Java verwendet die späte Bindung für alle nicht endgültigen, nicht privaten Instanzmethoden. So wird Polymorphie implementiert. Alle Anrufe, die Sie kommentiert haben, werden zur Laufzeit festgelegt.

In

A a=new A(); 
a.foo(); 

a verweist ein A Objekt so A ‚s Implementierung gefunden wird, gebunden und verwendet werden.

In

B b=new B(); 
b.foo(); 

b verweist auf ein B Objekt so B ‚s Implementierung gefunden wird, gebunden und verwendet.

In

ref=b; 
ref.foo(); 

ref verweist auf ein B Objekt so B ‚s Implementierung gefunden wird, gebunden und verwendet.

Der statische (deklarierte) Typ der Variablen wird nur vom Compiler verwendet, um zu verifizieren, dass eine solche Methode auf diesen Typ zugreifbar ist.

Verwandte:

6

Wrong in allen Punkten. Die aufzurufende Methode wird zur Laufzeit festgelegt, in jedem Fall hier basierend auf dem Laufzeittyp des Objekts. Die einzigen Entscheidungen, die während der Kompilierung getroffen werden, sind Aufrufe an finale, private oder statische Methoden oder Auswahlen in einer Menge überladener Methoden (die immer noch zu Laufzeitoptionen führen können, wenn die überladenen Methoden nicht endgültig, privat oder statisch sind).

)
0

Betrachten der Aussage

A ref; //reference of A 
    ref = new B();//Object of B 
     ref.f2(); 

Hier ref eine Referenz von class A ist, und es hat die Adresse des Objektes der class B f2() ist eine overridden Methode.

Wenn der Compiler eine solche Anweisung erkennt, bindet er den Funktionsaufruf nicht an eine Definition. Es validiert nur den Anruf.

Die Bindung solcher Aufrufe bleibt für die Laufzeitumgebung bestehen. Zur Programmlaufzeit identifiziert das System den Datentyp des Objekts und bindet den Funktionsaufruf mit der von der Objektklasse bereitgestellten Funktionsdefinition. Diese Art der Bindung zwischen Funktionsaufruf und Funktionsdefinition wird als "späte Bindung" oder "Laufzeitbindung" oder "Laufzeitpolymorphismus" oder "dynamischer Methodenversand" bezeichnet.

durchgehen this question and read my answer Beispiel wird auch dort gegeben.

0

Wenn Sie eine Methode für ein Objekt aufrufen, immer in Vererbung erinnern "am wenigsten modifizierte Version" der Methode aufgerufen werden. Dies ist nichts anderes, als die Methodenversion dynamisch aus der Hierarchie auszuwählen.

1

Alle Antworten hier sind größtenteils korrekt, aber es gibt einen wichtigen Punkt bezüglich der späten Bindung in Java.
Java führt keine "nach dem Buch" späte Bindung durch, wenn wir nach der Definition der späten Bindung gehen. Late Binding in seiner Buchdefinitionsform bedeutet, dass der Compiler bei einem Methodenaufruf keine Argumentprüfungen, keine Typprüfungen durchführen und alles der Laufzeit überlassen sollte - weil der Compiler möglicherweise keinen Zugriff auf den Methodenimplementierungscode hat (z. B. in der COM-Programmierung). Java überprüft jedoch zur Kompilierzeit selbst in einem polymorphen Szenario, dass die aufgerufene Methode und die Methodensignatur irgendwo in der Typhierarchie des Ausdrucks existiert, der die Methode qualifiziert. So zum Beispiel, sagen wir mal ich eine Methode foo1 auf ref aufrufen, die nicht in entweder nicht existiert A oder B:

A ref=null; 
ref=new B(); 
ref.foo1(); 
//This will not compile in Java, because java will check at compile time 
//for the method foo1 in the type hierarchy of A, which is the type of the 
// variable ref at compile time. 
//In pure late binding, however this would pass compilation and 
//throw an error at runtime. 

In einem reinen späte Bindung Szenario wird die Bestimmung, ob die Methode foo1() existiert oder nicht mit der richtigen Anzahl von Argumenten wird gemacht rein zur Laufzeit. In Java gibt es jedoch eine bestimmte Stufe der Überprüfung zur Kompilierzeit, um sicherzustellen, dass die Methode mit der richtigen Anzahl von Argumenten irgendwo in der Typhierarchie existiert.
Die einzige Zeit, die ich denke, Java führt pure späte Bindung ist, wenn man Reflexion verwendet, um eine Methode aufzurufen. Was Java tut, wird besser als dynamischer Dispatch und nicht als späte Bindung bezeichnet, aber jeder nennt es späte Bindung in Java und daher gibt es Verwirrung.

Verwandte Themen