class Bird{
    public Bird(){
    }

}

class Falcon extends Bird{
    public Falcon(){
    }

    public void fly(){
    System.out.println("Fly method in falcon");}
}

public class Test{
    public static void main (String args[]){
        Bird b=new Falcon();
        b.fly();    // error on this line
    }
}


上面的代码给了我一个编译时错误。谁能告诉我为什么?我正在使用JDK 1.8

最佳答案

基本上,如果将某些内容声明为Bird,则仅允许编译器“知道”编译器具有为Bird定义的方法。不允许知道为Bird的任何子类声明的任何方法(除非您使用强制转换)。

假设你要说

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


然后在someMethod中:

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


这基本上就是您正在做的事情。但是someMethod关于b的唯一了解是它是某种Bird。在那时,它无法分辨是Falcon,还是EmuKiwi之类的不具有Flight方法的东西(因为someMethod可以从窗口中的其他位置调用程序)。

当然,当程序看到b.fly()时,有可能在运行时检查这种鸟是否具有fly方法,如果没有,则抛出异常。一些语言可以做到这一点。 Java没有。

另外,如果您认为在这种情况下编译器应该知道:

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


bFalcon,因为它只是将其创建为Falcon:这是行不通的,因为它将需要过于复杂的语言规则,以使编译器能够看到b.fly()始终可以在其中运行情况,但在其他情况下并不总是有效。语言规则必须保持相当简单和一致,以确保程序可以在符合标准的任何编译器上运行。

但是,如果使用强制转换,则可以使用子类的方法:

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


这表示检查(在运行时)b是否为Falcon。如果是这样,您现在可以使用为Falcon定义的方法。如果不是,您将得到一个例外。

关于java - 此Java继承代码有什么错?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37649171/

10-09 09:36