class Animals {
.......
public void fly () {}
.....
}
class Unicorn extends animals {
public void fly() { // do something different }
public void walk() { }
}
public void doSomething (Animals p) {
p.walk(); //errors
p.fly(); //works depending on the class
}
public static void main()
{
Unicorn a = new Unicorn();
doSomething(a); //will not call walk()
}
据我所知,如果我们将一个unicorn类型的实例传递给doSomething,即使unicorn中的fly方法被覆盖,p.fly仍会调用修改后的版本,但是,它不知道walk方法,它为什么会发生,因为看起来编译器知道如何区分2,ethos,但不知道unicorn类中有哪些方法?并且,如果p持有对unicorn类型实例的引用,那么它不应该知道实例吗?因为它引用或指向实例,不是,但为什么不是这种情况???
答案 0 :(得分:3)
Subtype polymorphism以您提到的第一种方式工作,但它与您的其他示例无关。
Animal
实例能够响应方法fly()
,如果实例是Unicorn
(Animal
),则指定的版本更为明确方法将被调用(这是多态)。
但Animal
不是Unicorn
,因此walk()
不属于Animal
类,子类型关系不对称。在这种情况下:
void method(Animal animal) {
animal.walk();
}
method(new Unicorn());
您收到编译错误,因为method
的签名接受Animal
。在该方法中,编译时的变量动物(即使在运行时是Unicorn
)只是一个Animal
,它没有方法walk()
。因此,该方法中的类型的附加信息将被丢弃。
Java有一个静态强类型检查器,这意味着每个验证都是在编译时进行的。如果您传递了无法回答walk
方法的内容,则可以使用不同的编程语言来执行您想要的操作并抛出运行时错误。