我不理解此代码序列中的编译顺序

时间:2019-01-16 10:02:07

标签: java

我很难理解为什么在标有“ //// 1”的行中,程序将返回62而不是34。 谁能一步一步解释?我是Java的入门者,正在努力理解执行顺序。

class X {
        public void proc(X p){
            System.out.println(12);
        }
}

class Y extends X{
    public void proc(X p){
        System.out.println(62);
    }
}

class Z extends Y{
    public void proc(Z p){
        System.out.println(34);
    }
}

class Main4{
    public static void main(String[] args){
        X x = new Z();
        Y y = new Z();
        Z z = new Z();
        x.proc(z);////1
    }
}

任何帮助都会很棒!谢谢!

2 个答案:

答案 0 :(得分:1)

template<int data_size> struct在编译时从x.proc(z)类型(即x)的方法中选择。唯一可用的方法是X

还请记住,proc(X)中的public void proc(Z p)不会覆盖Z

答案 1 :(得分:1)

您之所以得到此结果,是因为您的proc方法不会相互覆盖。

最简单的方法是添加一个@Override注释:

static class Z extends Y {
    public Z() {
        v += 9;
    }

    @Override
    public void proc(Z p) {
        System.out.println(34);
    }
}

这将无法编译并显示错误消息

  

Test.Z类型的proc(Test.Z)方法必须重写或实现超类型方法

每当您打算覆盖某个方法时,最好添加此批注-这样编译器可以检查您是否确实这样做了。

要解决该错误并覆盖该方法以获得所需的输出,可以将参数的类型更改为X

static class Z extends Y {
    public Z() {
        v += 9;
    }

    @Override
    public void proc(X p) {
        System.out.println(34);
    }
}

现在,它再次编译,并产生34


您的示例中发生的事情是,您的类Z而非重载方法是将void proc(Z p)的重载方法void proc(X p)添加到X中的{em {1}}。重载解析基于编译时类型,因此只有X中的方法可用并被选择。该方法在Y中被覆盖,因此实际上是在运行时执行的。

因此,获得预期结果的另一种方法是保持XYZ不变,并将x的引用类型更改为{{1 }}:

Z

此版本在public static void main(String[] args) { Z x = new Z(); Y y = new Z(); Z z = new Z(); x.proc(z);//// 1 System.out.println(y.getV()); } 中调用 overloaded 方法,因为它是类型为Z的参数的最具体的重载。