java - 为什么调用错误的方法是: Strange inheritance behaviour

标签 java inheritance overriding

所以这道题是关于继承和方法重写的。 具体来说:子类具有与父类同名的方法,但签名不同的情况,例如:

class A has methodX(String arg)
class B extends A has methodX(int arg)

在正常情况下,将根据参数调用正确的方法。

但是在下面的代码中我遇到了一些我无法真正解释的奇怪行为:

static class A {
    public void method1() {
        System.out.println("m1.A");
    }
    public void method4(A arg) {        //Original method4
        System.out.println("m4.A");
    }
}

static class B extends A {
    public void method1() {
        System.out.println("m1.B");
    }
}

static class C extends B {
    public void method4(A arg) {        //Override method4 from Class A
        System.out.println("m4.C");
    }
}

static class E extends C {
    public void method1() {
        System.out.println("m1.E");
    }
    public void method4(E arg) {        //NO OVERRIDE: Same name, but different method4 than in class A or C
        System.out.println("m4.E");
    }
}


public static void main(String[] args) {
    A va = new A();
    B vb = new B();
    C vc = new C();
    E ve = new E();

    //At this point everything is fine
    ve.method4(ve);  //Calls method4 from class E based on parameter type - CORRECT
    ve.method4(va);  //Calls method4 from class C based on parameter type - CORRECT

    //After this code strange things happen
    vc = new E();
    vb = vc;

    vb.method1();    //Output: m1.E; method1 from class E is called - CORRECT
    vb.method4(vb);  //Output: m4.C; method4 from class C is called - why?

    vc.method1();    //Output: m1.E; method1 from class E is called - CORRECT
    vc.method4(vc);  //Output: m4.C; method4 from class C is called - why?
    vc.method4(ve);  //Output: m4.C; method4 from class C is called - why?

}

所以上面程序的输出是:

m4.E
m4.C

m1.E
m4.C  //why? Expected: m4.E

m1.E
m4.C  //why? Expected: m4.E
m4.C  //why? Expected: m4.E

行为

vb and vc

是我无法理解的。有什么想法吗?

最佳答案

我猜你期望 m4.E 被打印出来。但不要忘记,重载解析是在编译时执行的,而不是在执行时执行的。

CB 都没有可用的 method4(E) 方法,因此编译器解析对 method4( A) 方法...不会E 覆盖。您在问题中对 m4.C//why? 的所有调用都是对具有签名 method4(A) 的方法的调用,在 E 的实例上调用。现在 E 没有覆盖 method4(A),所以它保留在 C 中的实现,打印 m4.C.

这里没有发生任何奇怪的事情。

关于java - 为什么调用错误的方法是: Strange inheritance behaviour,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26220799/

相关文章:

java - 换算成小数点后2位

c++ - 派生对象之间的特殊交互(即多重分派(dispatch))

c++ - 从另一个类中访问私有(private)数据成员

c# - 有没有办法强制派生类实现抽象类或嵌套在基类中的接口(interface)?

java - 随着添加更多线程,Java线程似乎加快了速度

java - 模型中的必填字段

css - 覆盖 :hover text-decoration in a different class

java - 如何在方法内重写 Runnable?

ruby-on-rails - 覆盖 Controller 中的 protect_from_forgery 策略

java - 为什么每次刷新页面时 weblogic 都会创建新 session ?