多态性和动态绑定

Polymorphism and Dynamic Binding

假设我们有如下三个 classes

public class Woo extends Zoo {
    public String one() {
        return "wee" + this.two();
    }
    public String extra() {
        return "eek" + this.one();
    }
}

public class Zoo {
    public String one() {
        return "zee";
    }
public String two() {
        return "zow";
    }
}

public class Yoo extends Woo {
    public String two() {
        return "yow";
    }
}

假设我们声明了变量:

 Zoo z = new Yoo();

的输出是什么
System.out.println(z.one() + " " + z.two() + " " + z.extra()); 

是吗?

我的编译器不允许我编译说

no method in Zoo has extra

但我认为,由于 z 的实际类型是 class Yoo,并且 Yoo 继承了 ZooWoo class, z.extra() 行得通....?

即使您为 z 分配了一个 Yoo 类型的值,它仍然是一个 Zoo 对象。因此,Java 无法知道 extra 方法。您必须将 z 强制转换为 YooWoo 才能访问该方法。例如:

Zoo zoo = new Yoo();
Yoo yoo = (Yoo) zoo;

yoo.extra();

或者...

Zoo zoo = new Yoo();
Woo wyoo = (Woo) zoo;

wyoo.extra();

你甚至可以做到

Zoo zoo = new Yoo();
((Woo) zoo).extra();

并省略一行。


此外,假设您要覆盖 Yoo class 中的 extra。从上面的第二个例子调用 wyoo.extra() 会从 Yoo class 调用覆盖版本,因为 Java 不关心方法的内容,只关心方法保证存在。

如果您在调用 extra 之前将 z 的类型固定为 Yoo 或强制转换为 Yoo (正如其他答案描述的那样),您将能够编译并且输出应该是

weeyow yow eekzee