• 请不要在回答技术问题时复制粘贴 AI 生成的内容
diangdiang
V2EX  ›  程序员

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

  •  
  •   diangdiang · Oct 5, 2017 · 4258 views
    This topic created in 3318 days ago, the information mentioned may be changed or developed.
    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
    }
    

    }

    21 replies  •  2017-10-07 15:01:01 +08:00
    diangdiang
    diangdiang
    OP
    Oct 5, 2017
    1
    校招笔试题,搞不懂啊,谢谢 ~
    rogerchen
    rogerchen
    Oct 5, 2017
    2
    a2 中 B and B 对应的 overloading 不参与 resolution
    diangdiang
    diangdiang
    OP
    Oct 5, 2017
    3
    为啥不参与呢,能详细点吗?小白求助
    rogerchen
    rogerchen
    Oct 5, 2017
    4
    @diangdiang a2 的类型是 A,A 没有 public String show(B obj) 这个方法。
    diangdiang
    diangdiang
    OP
    Oct 5, 2017
    5
    哎呀呀,妙啊!多谢大佬
    ioc
    ioc
    Oct 5, 2017 via Android
    6
    考重载和多态的混淆?
    sosloop
    sosloop
    Oct 5, 2017 via Android
    7
    就是考多态,函数重载和重写
    jimisun
    jimisun
    Oct 6, 2017 via Android
    8
    @rogerchen 既然 A 类型没有 public String show(B obj 这个方法 为什么 a2.show(b);还能传入 b 类型的参数呢?
    lihongjie0209
    lihongjie0209
    Oct 6, 2017
    9
    这是函数重写, 多态(动态绑定)的基础是有一个类型(interface), 然后有不同的类(class)来实现, 最后在运行时(runtime)绑定.
    Spectre
    Spectre
    Oct 6, 2017
    10
    @jimisun 同疑惑
    Sikoay
    Sikoay
    Oct 6, 2017 via Android
    11
    a2 向上转型为 A,这时 show( B obj)方法丢失,然后调用 a2.show(b)时,由于 a2 中只有重载 show(A obj)过的方法,即调用此方法,输出"B and A",不知道这样解释对不对
    Sikoay
    Sikoay
    Oct 6, 2017 via Android
    12
    @jimisun
    @Spectre

    因为 B 为 A 的子类啊,所以即使 show(B obj)丢失之后也能够传入 B,但是此时传入的 B 已经被向上转型为 A 了
    Spectre
    Spectre
    Oct 6, 2017
    13
    @Sikoay B 继承于 A 能传 A 的都能传 B 好像是哎
    Sikoay
    Sikoay
    Oct 6, 2017 via Android
    14
    @Spectre 是的,但是在传递 A 的方法中就不能调用 B 的方法,但是还可以调用 B 重载的 A 的方法,并且能够正常运行,这就是运行时绑定
    wenzhoou
    wenzhoou
    Oct 6, 2017 via Android
    15
    编译后 调用的是 invokevirtual instance:a2 method:show ( A )
    编译时候就决定了一部分。运行时候决定了另一部分。
    Doodlister
    Doodlister
    Oct 6, 2017
    16
    B 是 A 的子类 A a2 = new B(); 是 B 向父类向上转型, 所以只能调用父类中声明的方法。即 show(A obj)。
    a2.show(b); 这样调用也是没毛病的 因为 b 是 A 的子类对象 所以 可以向上转型为 A 类型作为参数。
    guodong110
    guodong110
    Oct 6, 2017 via Android
    17
    承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。这里 this.show((super)O)满足,又由于在子类向上转型的时候,如果调用的方法是非静态方法且被子类覆写了,那么程序将会调用的是子类的方法,故输出 B and A
    8rB61FLBPVSxW2C8
    8rB61FLBPVSxW2C8
    Oct 6, 2017
    18
    声明 a2 的 A 类是静态类型,B 是实际类型,经过动态绑定后,调用的是实际实际类型中的方法
    loopback
    loopback
    Oct 6, 2017
    19
    静态多分派(两个宗量)
    动态单分派(一个宗量)
    vwok
    vwok
    Oct 7, 2017 via Android
    20
    diangdiang
    diangdiang
    OP
    Oct 7, 2017
    21
    多谢各位热心 V 友!
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5120 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 62ms · UTC 06:18 · PVG 14:18 · LAX 22:18 · JFK 01:18
    ♥ Do have faith in what you're doing.