此问题取自 AP 计算机科学实践测试。
public class Bird
{
public void act()
{
System.out.print("fly");
makeNoise();
}
public void makeNoise()
{
System.out.print("chirp");
}
}
public class Dove extends Bird
{
public void act()
{
super.act();
System.out.print("waddle");
}
public void makeNoise()
{
super.makeNoise();
System.out.print("coo");
}
}
假设以下声明出现在 Bird 或 Dove 以外的类中:
Bird pigeon = new Dove();
调用 pigeon.act()
的结果打印了什么?
我以为答案会是“fly chirp”,但教科书上说答案是“fly chirp coo waddle”。我认为“鸽子”只能访问 Bird 中可用的方法?我的印象是,如果用户想要访问 Dove 中的方法,则必须将“鸽子”强制转换为 Dove。
Bird pigeon = new Bird();
会给出相同的输出吗? Dove pigeon = new Dove();
怎么样?
最佳答案
长话短说,当您访问 pigeon
的 act
方法时,会调用 Dove
的覆盖。
I thought that 'pigeon' could only access methods available in Bird?
这当然是正确的,至少对于没有应用转换的情况。但是,act
方法在 Bird
类(pigeon
的静态已知类型)上可用,因此调用可以正常编译。
但是,访问 方法只是能够调用它们。当您调用它们时执行什么方法是在运行时根据 pigeon
的 dynamic 类型决定的。这就是方法覆盖发挥作用的地方,因为 Dove
覆盖了 Bird
的方法,但除此之外它还调用了 Bird
的方法。这就是代码命中所有四个打印输出的原因。
Would
Bird pigeon = new Bird();
give the same output?
不,输出会不同,因为在这种情况下,pigeon
的动态和静态类型是相同的,即 Bird
,所以只有 Bird
的实现将被调用。
关于java - 为什么这个对象可以访问它的父类的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43636366/