
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 }
}
1 diangdiang OP 校招笔试题,搞不懂啊,谢谢 ~ |
2 rogerchen Oct 5, 2017 a2 中 B and B 对应的 overloading 不参与 resolution |
3 diangdiang OP 为啥不参与呢,能详细点吗?小白求助 |
4 rogerchen Oct 5, 2017 @diangdiang a2 的类型是 A,A 没有 public String show(B obj) 这个方法。 |
5 diangdiang OP 哎呀呀,妙啊!多谢大佬 |
6 ioc Oct 5, 2017 via Android 考重载和多态的混淆? |
7 sosloop Oct 5, 2017 via Android 就是考多态,函数重载和重写 |
8 jimisun Oct 6, 2017 via Android @rogerchen 既然 A 类型没有 public String show(B obj 这个方法 为什么 a2.show(b);还能传入 b 类型的参数呢? |
9 lihongjie0209 Oct 6, 2017 这是函数重写, 多态(动态绑定)的基础是有一个类型(interface), 然后有不同的类(class)来实现, 最后在运行时(runtime)绑定. |
11 Sikoay Oct 6, 2017 via Android a2 向上转型为 A,这时 show( B obj)方法丢失,然后调用 a2.show(b)时,由于 a2 中只有重载 show(A obj)过的方法,即调用此方法,输出"B and A",不知道这样解释对不对 |
12 Sikoay Oct 6, 2017 via Android |
14 Sikoay Oct 6, 2017 via Android @Spectre 是的,但是在传递 A 的方法中就不能调用 B 的方法,但是还可以调用 B 重载的 A 的方法,并且能够正常运行,这就是运行时绑定 |
15 wenzhoou Oct 6, 2017 via Android 编译后 调用的是 invokevirtual instance:a2 method:show ( A ) 编译时候就决定了一部分。运行时候决定了另一部分。 |
16 Doodlister Oct 6, 2017 B 是 A 的子类 A a2 = new B(); 是 B 向父类向上转型, 所以只能调用父类中声明的方法。即 show(A obj)。 a2.show(b); 这样调用也是没毛病的 因为 b 是 A 的子类对象 所以 可以向上转型为 A 类型作为参数。 |
17 guodong110 Oct 6, 2017 via Android 承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。这里 this.show((super)O)满足,又由于在子类向上转型的时候,如果调用的方法是非静态方法且被子类覆写了,那么程序将会调用的是子类的方法,故输出 B and A |
18 8rB61FLBPVSxW2C8 Oct 6, 2017 声明 a2 的 A 类是静态类型,B 是实际类型,经过动态绑定后,调用的是实际实际类型中的方法 |
19 loopback Oct 6, 2017 静态多分派(两个宗量) 动态单分派(一个宗量) |
20 vwok Oct 7, 2017 via Android |
21 diangdiang OP 多谢各位热心 V 友! |