假设我有一个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?
假设我有一个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?
两者都使用 B 的 foo()。A a 只是访问 B 的方法,因为 B 是实例。
将 A a 视为实例的接口,在本例中:new B()
这是一个示例(在 groovy 中): http: //groovyconsole.appspot.com/script/616002
在A a = new B();
和B b = new B();
a和b是B类的实例,所以两次b 的 foo()方法都会被调用。
因为如果方法在子类(在本例中为B类)中被覆盖,则子对象的实例将调用该方法存在于它自己的类中,而不是在父类(在本例中为A类)中。
对于这两种情况,它将调用 B 的 foo 方法。在java中,所有方法调用都是动态调度的——不管你调用什么引用或上下文——方法调用将基于对象的类型。
方法调用仅取决于调用方法的对象的类型,而不取决于用于调用的引用类型。
由于在您的情况下,在这两种情况下,都将调用 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