这个java继承代码有什么问题?

时间:2016-06-06 03:32:49

标签: java oop inheritance default-constructor

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

1 个答案:

答案 0 :(得分:4)

基本上,如果你将某些东西声明为Bird,那么编译器的唯一内容就是"允许"要知道它具有为Bird定义的方法。不允许知道为Bird的任何子类声明的任何方法(除非您使用强制转换)。

假设你要说

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

然后,在someMethod

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

这与您正在做的事情基本相同。但someMethodb的唯一了解是,Bird是某种Falcon。在那一点上,它无法告诉它是Emu,还是像KiwisomeMethod这样没有飞行方法的东西(因为可以从程序中的其他地方调用b.fly()

当然,程序在看到fly时,可能会在运行时检查 这种鸟是否有Bird b = new Falcon(); b.fly(); 方法,然后抛出如果它没有例外则是例外。有些语言可以做到。 Java没有。

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

b

FalconFalcon,因为它只是将其创建为b.fly():它不起作用,因为它需要过于复杂的语言规则才能允许编译器看到Bird b = new Falcon(); ((Falcon)b).fly(); 在这种情况下始终有效,但在其他情况下不会总是有效。语言规则需要保持相当简单和一致,以确保程序适用于符合标准的任何编译器。

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

b

这表示检查(在运行时)Falcon是否为Falcon。如果是,您现在可以使用为{{1}}定义的方法。如果不是,您将获得例外。