为啥此代码打印 20 20 而不是 20 10? [复制]
Posted
技术标签:
【中文标题】为啥此代码打印 20 20 而不是 20 10? [复制]【英文标题】:why this code is printing 20 20 instead of 20 10? [duplicate]为什么此代码打印 20 20 而不是 20 10? [复制] 【发布时间】:2017-10-07 16:21:08 【问题描述】:package package1;
public class MyClassA
protected int size;
public MyClassA()
protected int getAge()
return 10;
public int callAge()
return getAge();
package package2;
import package1.MyClassA;
public class MyClassB extends MyClassA
protected int getAge()
return 20;
private int superesult()
return super.callAge();
public static void main(String args[])
MyClassB classb = new MyClassB();
System.out.println(classb.getAge());
System.out.println(classb.superesult());
当我调用 getAge 和 superresult 方法时,我期望 20 10 作为输出,但代码正在打印 20 20。提前致谢。
【问题讨论】:
因为getAge
被覆盖了。
superresult
在MyClassA
中调用callAge
,callAge
调用重写的方法getAge
。 MyClassB
中的覆盖返回 20。这就是覆盖的作用。
“我期待 20 10”你为什么期待这样的结果?
@Pshemo:我认为 OP 已经考虑到,如果您通过 super
调用某些内容,您会“改变上下文”,因为所有调用现在都在“超级域”中。跨度>
这里要理解的概念叫做多态。从某种意义上说:问“为什么”这样的事情没有多大意义;更像:这就是多态性在 Java 中的表现方式。所以你必须了解这个概念是如何运作的;然后你就会明白你正在观察的行为。
【参考方案1】:
简答:您调用callAge
,因为它在A
中实现。但是该方法调用getAge
被覆盖(因此Java 遵循在B
中完成的实现)。
加长版:
当你打电话时:
classb.superesult();
它将调用super.callAge()
,这意味着A
类的callAge()
被执行。 callAge()
在他的部分调用 getAge()
但由于该对象是类 B
的实例并且 getAge()
被覆盖,它返回 20
。
请注意,如果您调用 super.foo()
,您只会调用 超级 foo。 super
因此并不意味着你“改变上下文”:所有由 super 调用产生的调用仍然通过对象上的动态绑定来解决(并且对象仍然是一个实例B
)。所有调用foo
都可以被覆盖(除非这些调用被标记为final
)。在大多数情况下,这是理想的行为。
【讨论】:
【参考方案2】:它是polymorphism。你已经在getAge()
方法中使用了 ovveridden。因此,当您调用该方法时,ovverdien 方法始终会执行。
Java 虚拟机 (JVM) 为每个变量中引用的对象调用适当的方法。它不调用由变量类型定义的方法。这种行为称为虚方法调用,展示了 Java 语言中重要的多态特性的一个方面。
【讨论】:
【参考方案3】:这是因为您在子类中覆盖了getAge()
方法。现在MyClassB classb = new MyClassB();
指向子类,所以会调用它的方法而不是父方法
【讨论】:
以上是关于为啥此代码打印 20 20 而不是 20 10? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥它只打印文本文件的一个单词而不是整个文本文件到 html 文件
如何从22个文本框中为20个文本框创建一个代码,而不是相同的20倍
为啥我应该使用 char 而不是 varchar? [复制]