Java中的动态调度

时间:2011-12-21 05:09:31

标签: java subtype dynamic-dispatch

假设我有一个类A,它定义了一个方法bar()。方法bar()调用另一种方法foo()。然后,我在A中展开B并覆盖foo(),并且不会覆盖bar()(因此它会被继承)。在这两种情况下调用哪个foo()

A a = new B();
a.bar(); // A or B's foo called?

B b = new B();
b.bar(); // A or B's foo called?

4 个答案:

答案 0 :(得分:3)

两者都使用B的foo()。 a只是访问B的方法,因为B是实例。

将A a视为实例的接口,在本例中为:new B()

这是一个例子(在groovy中): http://groovyconsole.appspot.com/script/616002

答案 1 :(得分:1)

A a = new B();B b = new B();

a b B 类的实例,因此将同时调用 b的foo()方法。

因为如果在子类中重写了方法(在这种情况下, B 类),那么子对象的实例将调用它自己的类中不存在于父类中的方法(在本例中,< strong> A 类)。

答案 2 :(得分:0)

对于这两种情况,它将调用B的foo方法。在java中,所有方法调用都是动态调度的 - 与您调用它的引用或上下文无关 - 方法调用将基于对象的类型。

答案 3 :(得分:0)

方法调用仅取决于调用方法的对象的类型,而不取决于用于调用的引用类型。

因为在你的情况下,在这两种情况下,都要调用B类对象的方法,两者都会调用B的foo()。

class C {
    public void foo() {
        System.out.println("foo in C");
    }

    public void bar() {
        System.out.println("calling foo");
        foo();
    }
}


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


public class A {


    public static void main(final String[] args) {
        C c = new B();
        c.bar(); // C or B's foo called?

        B b = new B();
        b.bar(); // C or B's foo called?

    }

输出是:

calling foo
foo in B
calling foo
foo in B