Java 我不理解这一系列代码的编译顺序

Java 我不理解这一系列代码的编译顺序,java,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); } } cl

我无法理解为什么在标有“///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
    }
}
任何帮助都会很棒!谢谢大家!

x.proc(z)
在编译时选择
x
类型(即
x
)中的方法。唯一可用的方法是
proc(X)


还要记住,
Z
中的
public void proc(Z p)
不会覆盖
public void proc(X p)
您得到这个结果是因为
proc
方法不会相互覆盖

查看这一点的最简单方法是添加一个
@Override
-注释:

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

    @Override
    public void proc(Z p) {
        System.out.println(34);
    }
}
这将无法编译,并显示错误消息

type 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
除了
X
中的
void proc(xp)
方法之外,还添加了一个重载方法
void proc(zp)
,而不是重写。重载解析基于编译时类型,因此只有
X
中的方法可用并被选择。此方法在
Y
中被重写,因此这就是在运行时实际执行的方法

因此,获得预期结果的另一种方法是保持
X
Y
Z
不变,并将
X
的引用类型更改为
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());
}
此版本调用
Z
中的重载方法,因为它是
Z
类型的参数的最特定重载

proc(Z)
不会覆盖
proc(X)