对象的引用如何在多态中工作?

时间:2014-02-21 00:15:52

标签: java reference polymorphism

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类型实例的引用,那么它不应该知道实例吗?因为它引用或指向实例,不是,但为什么不是这种情况???

1 个答案:

答案 0 :(得分:3)

Subtype polymorphism以您提到的第一种方式工作,但它与您的其他示例无关。

Animal实例能够响应方法fly(),如果实例是UnicornAnimal),则指定的版本更为明确方法将被调用(这是多态)。

Animal不是Unicorn,因此walk()不属于Animal类,子类型关系不对称。在这种情况下:

void method(Animal animal) {
  animal.walk();
}

method(new Unicorn());

您收到编译错误,因为method的签名接受Animal。在该方法中,编译时的变量动物(即使在运行时是Unicorn)只是一个Animal,它没有方法walk()。因此,该方法中的类型的附加信息将被丢弃。

Java有一个静态强类型检查器,这意味着每个验证都是在编译时进行的。如果您传递了无法回答walk方法的内容,则可以使用不同的编程语言来执行您想要的操作并抛出运行时错误。