【问题标题】:Java polymorphism function callsJava多态函数调用
【发布时间】:2015-11-18 06:49:48
【问题描述】:

无法理解为什么两个函数调用的输出为“3”和“4”。对于,

g2.foo( t1 );

在编译时,g2 是类型 A,它查找 foo(type C),它在它的主类中找不到,所以它查找它的子类 B,然后是 C。所以 foo(... ) 应该绑定到

public void foo(C p) {
    System.out.println("5");
}

子类 C 对吗?

然后在运行时 g2 将是 C 类型并调用 foo(C p) 将导致输出“5”。我不确定我对多态性的逻辑/理解哪里错了。

class A {
    public void foo(A p) {
        System.out.println("1");
    }
}

class B extends A {
    public void foo(B p) {
        System.out.println("2");
    }
}

class C extends B {
    public void foo(A p) {
        System.out.println("3");
    }

    public void foo(B p) {
        System.out.println("4");
    }

    public void foo(C p) {
        System.out.println("5");
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        A g2 = new C();
        B r2 = new C();
        C t1 = new C();

        g2.foo(t1); // 3

        r2.foo(new C()); // 4
    }
}

【问题讨论】:

    标签: java polymorphism extends


    【解决方案1】:

    要记住的主要事情是,重载方法是在编译时根据调用该方法的实例的编译时类型来选择的。运行时类型仅确定所选方法是否被运行时类型的实现覆盖。

    g2.foo(t1)

    g2 有一个编译类型A,这意味着在编译时只能选择public void foo(A p)。在运行时 g2C 的实例中,这意味着 public void foo(A p)C 被调用,它打印 3。

    r2.foo(新 C())

    r2 有一个编译类型B,因此可以在编译时选择public void foo(A p)public void foo(B p)public void foo(B p) 是最好的重载匹配(因为BA 更具体)。在运行时,r2C 的一个实例,因此调用Cpublic void foo(B p),并打印4。

    【讨论】:

      【解决方案2】:

      无论何时重写一个函数,派生类的虚拟表(v-table)都会将该函数与其实现映射。因此,函数调用将调用该特定类的 v-table 给出的实现。

      在你的情况下, A g2 = new C();创建 C 的实例,因此 v-table 将 foo 函数与其(C 的)实现映射。

      现在,当函数调用发生时,即在 g2.foo(t1) 上,将调用类 C 的实现,因为它已映射,因此打印 3。

      【讨论】:

        【解决方案3】:

        在编译时,g2 是类型 A,它查找 foo(type C),它在其主类中找不到,因此它查找其子类 B,然后查找 C .所以 foo(...) 应该绑定到 ...

        你的这种理解是错误的。

        在编译期间,由于A类型中没有foo(C),这标志着方法foo(A)将被调用(因为AC的超类型,它是匹配的最具体的方法)。

        在运行时,C 的特定方法(foo(A))的实现被调用并打印3。下次调用也类似。

        【讨论】:

          【解决方案4】:

          当你调用 g2.foo(t1) g2 得到 A 的 Compile 类型 Object,这意味着 A 的那个方法,即

           public void foo(A p)
          

          但在运行时 g2 是 C 类的对象,因此调用 public void foo(A p)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-17
            • 2020-12-04
            • 1970-01-01
            相关资源
            最近更新 更多