Der obige Code gibt mir einen Kompilierzeitfehler. Kann mir jemand sagen warum? Ich benutze JDK 1.8Was ist falsch in diesem Java-Vererbungscode?
Antwort
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
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.
danke für so eine ausführliche Erklärung. – dgupta3091
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
'Bird' hat keine' fly'-Methode in seiner '* public ** Schnittstelle *** angegeben. –
* "gibt mir einen Kompilierzeitfehler" * ist eine unvollständige Beschreibung Ihres Problems. Welcher Fehler? – Andreas
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