Java 为什么这个静态绑定没有';你不能像我期望的那样工作吗?
我有一个关于这个程序如何选择方法的问题 代码(构造函数除外): 主要内容: 我不明白为什么Java 为什么这个静态绑定没有';你不能像我期望的那样工作吗?,java,overriding,overloading,dynamic-binding,static-binding,Java,Overriding,Overloading,Dynamic Binding,Static Binding,我有一个关于这个程序如何选择方法的问题 代码(构造函数除外): 主要内容: 我不明白为什么f2.m(s1)打印100。 我个人理解,如果有两个同名的方法,如果有重载,则选择静态类型,如果重写,则选择动态类型 f1.m(s1)动态搜索父.m(子)方法,但它不存在,而是选择了父.m(父) f2.m(s1)动态搜索一个Son.m(Son)方法,该方法存在并且是一个重载,因此我认为它现在应该优先考虑静态类型,并搜索一个父.m(子)方法,该方法不存在,但最近的是父.m(父)。 相反,选择了Son.m(父)
f2.m(s1)
打印100。
我个人理解,如果有两个同名的方法,如果有重载,则选择静态类型,如果重写,则选择动态类型
f1.m(s1)
动态搜索父.m(子)
方法,但它不存在,而是选择了父.m(父)
f2.m(s1)
动态搜索一个Son.m(Son)
方法,该方法存在并且是一个重载,因此我认为它现在应该优先考虑静态类型,并搜索一个父.m(子)
方法,该方法不存在,但最近的是父.m(父)
。
相反,选择了
Son.m(父)
方法:它是由Son.m(子)方法重载的方法,好吧,但它不是从静态搜索出来的,所以为什么选择它?f2声明为父,然后由子实例化。在父类中,唯一的m方法是接受父作为输入参数的方法。因此,当您通过子类实例化f2时,只有intm(父f)
可用于重写。(只要关注f2,就没有int m(Son f)
方法)这就是f2.m(s1)返回100的原因。f2
是一个类型为Father
的引用。即使它引用的对象是子对象,编译器仍然只允许在访问该类型的引用时使用父对象中存在的任何方法。因此,除了使用签名为intm(父亲)
的方法之外,别无选择(因为它是父亲中唯一存在的方法)。由于Son
对此方法有一个覆盖,因此将执行该覆盖
f2.m(s1)动态搜索子.m(子)方法
这就是你的错误根源所在。它不是在寻找
Son.m(Son)
方法,而是在寻找Father.m(Son)
方法并找到Father.m(Father)
方法。调用覆盖将在稍后进行。让我们逐一分析
f2 = new Son(3,10);
根据概念,子对象将在运行时绑定
然后你打电话来了
f2.m(s1)
现在,当它在子对象中搜索m方法时。它发现其中有两个1。m(父亲f)和2。m(儿子s)
但引用f2属于父类型,并且子对象和父对象之间只有m(父f)是公共的,因此子对象的m(父f)将在运行时被选择执行(简而言之,在父对象作为引用时,m(子s)将不可见)。这就是为什么你会看到这样的结果
您也可以调试代码。它将向您显示相同的执行流程。您确定正确解释了结果吗?可能将所有ur方法简化为只返回1代码>,
返回2代码>,返回3
,甚至更好:添加一些来自…
的hello打印。为了确保这不是你复杂的数学问题,我无意中输出了相同的数字。这段代码不是我的,我正在研究它。我相信它打印出101(1+100)我有解决方案,也测试了它。我想看看我的理解是否有缺陷。你必须在这里展示共构造函数。想想Dog
类中的bark()
方法。现在做动物a=新狗()代码>。您不能调用a.bark()
,尽管实际实例是一只Dog
。同样的情况也发生在这里。仅存在于Son
中的方法不可见,无法调用。在选择正确的签名后,java会考虑它想要调用的方法签名的覆盖。哦,你的意思是如果f2是子,它就不“看”父。父方法,它只能看到子。M(父亲)它选择它?是的,F2声明为父亲,但实例化为子,所以当你调用f2.m(父)时(记住f2被声明为父,所以它只看到m(父))真正被调用的是Son.m(父),因为Son类重写了来自父的这个方法。非常好的解释!我更进一步地说,它甚至没有“寻找”父.m(子)
方法。f2
穿着父亲的衣服
,对外界来说,它只是一个父亲
,因此被调用的是父亲.m(父亲)
方法。但在内部f2
仍然是一个儿子
,因此就像一个儿子
,并执行自己的m(父亲)
重写,同时静默地接受该参数是Son
。
f2 = new Son(3,10);
f2.m(s1)