假設我有一個類A
,它定義了一個方法bar()
。方法bar()
調用另一種方法foo()
。然後,我在B
中延伸A
並覆蓋foo()
,並且不覆蓋bar()
(因此它被繼承)。在這兩種情況下哪個叫foo()
?Java中的動態分派
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()
。然後,我在B
中延伸A
並覆蓋foo()
,並且不覆蓋bar()
(因此它被繼承)。在這兩種情況下哪個叫foo()
?Java中的動態分派
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()。 因爲B是實例,所以a只是訪問B的方法。
認爲一個一個作爲接口的實例,在這種情況下:)新B(
下面是一個例子(在常規): http://groovyconsole.appspot.com/script/616002
它將調用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
在A a = new B();
和B b = new B();
一個和b是B的實例類,以便既時間B的FOO()方法將被調用。
因爲如果方法在子類中重寫(在這種情況下,乙類),那麼子對象的實例會調用存在於父母的類它自己的類不是方法(在這種情況下,一個類) 。
在這種情況下你說的是真實的,但我會小心地說「所有的方法調用都是動態調度的」。 Java沒有多個派遣。例如,如果您有一個重載的方法,則根據您傳入的參數的運行時類型,被調用的方法是* not * dynamic。 – 2011-12-21 05:27:18
我說的是基於調用方法的對象的類型 - 而不是類型的論據。 – gkamal 2011-12-21 05:40:51