2
我很困惑在Java中調度方法。爲什麼第一個方法「a.m1(b)」調用A類?Java調度 - 運行時類型
調用變量是a。它的運行時類型是B,不是嗎?
class A {
public void m1(A a){
System.out.println("A-m1");
}
public void m1(){
System.out.println("A-m1");
}
}
class B extends A {
public void m1(B b){
System.out.println("B-m1");
}
public void m1(){
System.out.println("B-m1");
}
}
public class HelloWorld {
public static void main(String[] args) {
B b = new B();
A a = new B();
a.m1(b);//prints A-m1
a.m1();//prints B-m1
}
}
非常感謝您的回答。但是,我不明白爲什麼不。例如,http://java-x.blogspot.de/2006/05/double-dispatch-in-java.html上的「ast1.collideWith(sp)」並未真正使用重載解析來理解,因爲雖然小行星也有collideWith(Spaceship),它與ExplodingAsteroid一致。你能解釋一下嗎? – Sammy 2013-02-14 18:11:34
@Sammy你的情況與你鏈接的例子並不相似。 'collideWith(SpaceShip)'和'collideWith(GiantSpaceShip)'在編譯時很好解決,因爲當它們被調用時,'this'總是包含類的類型 - 當你遇到這種情況時,你故意使編譯時類型的'a'爲'A'。覆蓋方法也覆蓋了它們在超類中的相應重載,而不是重載不同的方法簽名。 (我不確定編譯器如何解決這種歧義的確切規則。) – millimoose 2013-02-14 18:16:21
@Sammy或者,換句話說,有兩個步驟會發生:** 1。** * overload *是使用接收器的編譯時類型*和*參數。 ** 2。** *覆蓋*是使用接收器的運行時類型確定的。不同之處在步驟2.在你的情況下,'A.m1(A)'方法根本不會在'B'中覆蓋。在你鏈接的小行星/宇宙飛船的例子中,'Asteroid.collideWith(Spaceship)'被ExplodingAsteroid.collideWith(Spaceship)所覆蓋(簽名是相同的),所以如果運行時的接收器類型是ExplodingAsteroid,被調用。 – millimoose 2013-02-14 18:53:06