2016-06-06 9 views
-1

Der obige Code gibt mir einen Kompilierzeitfehler. Kann mir jemand sagen warum? Ich benutze JDK 1.8Was ist falsch in diesem Java-Vererbungscode?

+6

'Bird' hat keine' fly'-Methode in seiner '* public ** Schnittstelle *** angegeben. –

+0

* "gibt mir einen Kompilierzeitfehler" * ist eine unvollständige Beschreibung Ihres Problems. Welcher Fehler? – Andreas

+2

Um etwas über Elliotts Kommentar zu erfahren: Wenn der Typ einen statischen Typ von 'Bird' hat, kann Java nur Methoden darauf aufrufen, dass er alle Vögel kennt. Sie haben auf Bird keine Methode 'fly()' deklariert, so weit Java es kann, könnte dieser Bird einer sein, der diese Methode nicht hat - und somit wird es Sie nicht aufrufen lassen. Java weiß zur Kompilierzeit nicht, dass "b" spezifisch ein Falcon ist, weil du es ausdrücklich gesagt hast, dass es nur eine Art von Vogel ist. – yshavit

Antwort

4

Grundsätzlich, wenn Sie etwas als Bird deklarieren, ist das einzige, was der Compiler "erlaubt" zu wissen ist, dass es die Methoden für Bird definiert hat. Es ist nicht erlaubt, über Methoden zu wissen, die für Unterklassen von Bird deklariert sind (es sei denn, Sie verwenden einen Cast).

Angenommen, Sie

Bird b = new Falcon(); 
someMethod(b); 

und dann in someMethod sagen

waren:

public void someMethod(Bird b) { 
    b.fly(); 
} 

Dies ist im Wesentlichen das gleiche, was Sie tun. Aber das einzige, was someMethod über b weiß ist, dass es eine Art von Bird ist. Es kann zu diesem Zeitpunkt nicht feststellen, ob es sich um eine Falcon oder etwas wie eine Emu oder Kiwi handelt, die keine Flugmethode hat (da someMethod von einer anderen Stelle im Programm aufgerufen werden kann).

Sicher, könnte es für das Programm möglich sein, wenn es b.fly() sieht, zur Laufzeit, ob diese Art von Vogel zu überprüfen fly Methode hat, und eine Ausnahme auslösen, wenn es nicht der Fall ist. Einige Sprachen machen das. Java nicht.

Auch, wenn Sie denken, dass der Compiler in diesem Fall wissen sollten:

Bird b = new Falcon(); 
b.fly(); 

dass b ein Falcon ist, weil es erstellt es nur als Falcon: das nicht, weil es nicht funktioniert würde übermäßig komplizierte Sprachregeln erfordern, damit ein Compiler sehen kann, dass b.fly() immer in diesem Fall funktioniert, aber in anderen Fällen nicht immer funktioniert. Sprachregeln müssen ziemlich einfach und konsistent gehalten werden, um sicherzustellen, dass Programme mit jedem Compiler funktionieren, der den Standard erfüllt.

Wenn Sie jedoch eine Besetzung verwenden, Sie können bei Methoden der Unterklassen erhalten:

Bird b = new Falcon(); 
((Falcon)b).fly(); 

Dies sagt zu überprüfen (zur Laufzeit), ob b ein Falcon ist. Wenn dies der Fall ist, können Sie nun die für Falcon definierten Methoden verwenden. Wenn nicht, erhalten Sie eine Ausnahme.

+0

danke für so eine ausführliche Erklärung. – dgupta3091

+1

Tolle Erklärung! Als zusätzlichen Kommentar für "einige Sprachen tun das. Java nicht" - das ist, allgemein gesprochen (und einige Feinheiten beschönigend), der Unterschied zwischen einer "statisch getippten" Sprache wie Java und einer "dynamisch typisierten" Sprache (wie Python, JavaScript und andere). – yshavit