有 Java 大佬在吗?遇到一个 动态绑定的问题,求指教

2017-10-05 21:22:21 +08:00
diangdiang  diangdiang
class A {
public String show(A obj) {
	return ("A and A");
}

}

class B extends A {

public String show(B obj) {
	return ("B and B");
}

public String show(A obj) {
	return ("B and A");
}

}

public class OverrideTest {

public static void main(String[] args) {

	A a2 = new B();
	B b = new B();
	
	String res = a2.show(b);
	System.out.println(res); // 感觉应该输出 B and B,实际输出 B and A
}

}

3185 次点击
所在节点   程序员  程序员
21 条回复
diangdiang
diangdiang
2017-10-05 21:24:35 +08:00
校招笔试题,搞不懂啊,谢谢 ~
rogerchen
rogerchen
2017-10-05 21:31:33 +08:00
a2 中 B and B 对应的 overloading 不参与 resolution
diangdiang
diangdiang
2017-10-05 21:34:13 +08:00
为啥不参与呢,能详细点吗?小白求助
rogerchen
rogerchen
2017-10-05 21:36:41 +08:00
@diangdiang a2 的类型是 A,A 没有 public String show(B obj) 这个方法。
diangdiang
diangdiang
2017-10-05 21:37:31 +08:00
哎呀呀,妙啊!多谢大佬
ioc
ioc
2017-10-05 23:44:30 +08:00
考重载和多态的混淆?
sosloop
sosloop
2017-10-05 23:54:06 +08:00
就是考多态,函数重载和重写
jimisun
jimisun
2017-10-06 00:08:16 +08:00
@rogerchen 既然 A 类型没有 public String show(B obj 这个方法 为什么 a2.show(b);还能传入 b 类型的参数呢?
lihongjie0209
lihongjie0209
2017-10-06 00:26:28 +08:00
这是函数重写, 多态(动态绑定)的基础是有一个类型(interface), 然后有不同的类(class)来实现, 最后在运行时(runtime)绑定.
Spectre
Spectre
2017-10-06 00:35:20 +08:00
@jimisun 同疑惑
Sikoay
Sikoay
2017-10-06 00:35:41 +08:00
a2 向上转型为 A,这时 show( B obj)方法丢失,然后调用 a2.show(b)时,由于 a2 中只有重载 show(A obj)过的方法,即调用此方法,输出"B and A",不知道这样解释对不对
Sikoay
Sikoay
2017-10-06 00:39:00 +08:00
@jimisun
@Spectre

因为 B 为 A 的子类啊,所以即使 show(B obj)丢失之后也能够传入 B,但是此时传入的 B 已经被向上转型为 A 了
Spectre
Spectre
2017-10-06 00:53:30 +08:00
@Sikoay B 继承于 A 能传 A 的都能传 B 好像是哎
Sikoay
2017-10-06 00:56:19 +08:00
@Spectre 是的,但是在传递 A 的方法中就不能调用 B 的方法,但是还可以调用 B 重载的 A 的方法,并且能够正常运行,这就是运行时绑定
wenzhoou
2017-10-06 07:55:12 +08:00
编译后 调用的是 invokevirtual instance:a2 method:show ( A )
编译时候就决定了一部分。运行时候决定了另一部分。
Doodlister
2017-10-06 09:17:10 +08:00
B 是 A 的子类 A a2 = new B(); 是 B 向父类向上转型, 所以只能调用父类中声明的方法。即 show(A obj)。
a2.show(b); 这样调用也是没毛病的 因为 b 是 A 的子类对象 所以 可以向上转型为 A 类型作为参数。
guodong110
2017-10-06 09:47:43 +08:00
承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。这里 this.show((super)O)满足,又由于在子类向上转型的时候,如果调用的方法是非静态方法且被子类覆写了,那么程序将会调用的是子类的方法,故输出 B and A
8rB61FLBPVSxW2C8
2017-10-06 10:03:16 +08:00
声明 a2 的 A 类是静态类型,B 是实际类型,经过动态绑定后,调用的是实际实际类型中的方法
loopback
2017-10-06 21:46:19 +08:00
静态多分派(两个宗量)
动态单分派(一个宗量)
vwok
2017-10-07 00:39:13 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/395556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX