Java多态 - 具体示例

mrg*_*grt 3 java polymorphism

我对以下示例有一些问题(更确切地说,有一个特定的行).这是代码(之后的问题):

public class Up
{
    public void cc(Up u) {System.out.println("A");}
    public void cc(Middle m) {System.out.println("B");}
}

public class Middle extends Up
{
    public void cc(Up u) {System.out.println("C");}
    public void cc(Down d) {System.out.println("D");}
}

public class Down extends Middle
{
    public void cc(Up u) {System.out.println("E");}
    public void cc(Middle m) {System.out.println("F");}
}

public class Test
{
    public static void main(String... args)
    {
        Up uu = new Up();
        Up pp = new Middle();
        Down dd = new Down();

        uu.cc(pp); // "A"
        uu.cc(dd); // "B"
        pp.cc(pp); // "C"
        pp.cc(dd); // "B"
        dd.cc(pp); // "E"
        dd.cc(dd); // "D"
    }
}
Run Code Online (Sandbox Code Playgroud)

现在uu.cc(pp);并且uu.cc(dd);非常明显,因为uu是一个实例,Up并且pp"看起来像"一样Up(在编译时).最合适的方法ddcc(Middle m)as dd的实例Down继承自Middle.

我遇到的问题最多的是pp.cc(dd);dd.cc(dd).关于在编译时或在运行时确定这些事情的时间和方式,我真的有点困惑.如果有人能帮我理解,我会很高兴.

Jon*_*eet 5

基本上,该方法签名被选择以基于编译时间类型所涉及的表达式的编译时间,并且执行被选择在执行时,基于实际执行只是的目标的方法的.

所以在编译时,pp.cc(dd)尝试找到匹配Up.cc(Down).最具体的匹配是Up.cc(Middle),这就是编译代码中的最终结果.现在在执行时,执行该操作将是Up.cc(Middle)因为Middle不会覆盖该方法签名.因此它打印"B".

现在在编译时,dd.cc(dd)尝试找到匹配.Down.cc(Down).这里有两个相关的选择 - 要么Middle.cc(Down)参数完全Down.cc(Middle)匹配,要么与目标类型完全匹配.编译器更喜欢Middle.cc(Down).在执行时,再次没有覆盖该方法Down,因此它打印"D".

重载决策规范的相关位是15.12,特别是15.12.2 - 确定方法签名.