[英]Is it method overriding or overloading?
public class Tester {
public static void main(String[] args) {
A a2 = new B();
a2.dosomething1(new B());
a2.dosomething2(new B());
}
}
class A {
public void dosomething1(A a){
System.out.println("Inside a dosomething1");
}
public void dosomething2(A a){
System.out.println("Inside a dosomething2");
}
}
class B extends A {
public void dosomething1(A a){
System.out.println("Inside b dosomething1");
}
public void dosomething2(B b){
System.out.println("Inside b dosomething2");
}
}
輸出量
Inside b dosomething1
Inside a dosomething2
輸出中的第一行顯然是由於方法重寫。 但是第二行背后的原因是什么? 為什么Java不像在運行時那樣調用B中定義的方法,它知道a2是B的對象。
您需要回答的問題是: B.dosomething2(B b)
完全替代A.dosomething2(A a)
嗎? 或者更具體地說:是否也可以將A.dosomething2(A a)
接受的每個參數值都傳遞給B.dosomething2(B b)
?
答案很簡單:不。
B obj_B= new B();
A obj_A= new A();
obj_B.doSomething2(obj_A);
上面的示例應清楚說明原因: obj_A
不是B
的實例,因此不能將其作為參數傳遞給B.dosomething2(B b)
。 這意味着這兩個方法雖然共享相同的名稱,但是卻不共享相同的簽名,這又意味着我們正在重載該方法而不是覆蓋它。
碰巧同時使用兩者都可以進行調用的事實是無關緊要的,因為根據變量a2
的類型( A
)而不是變量的運行時類,選擇在Java編譯時選擇要調用的重載方法是在編譯時發生。它指向( B
)的對象。
這類錯誤很容易偶然發生,特別是如果您改組方法並將其重命名。 為了避免在覆蓋時意外重載,請確保在打算覆蓋某些內容時始終使用@Override
批注,這樣編譯器會抱怨。
class B extends A {
@Override //this will compile fine
public void dosomething1(A a){
System.out.println("Inside b dosomething1");
}
@Override //this will fail compilation
public void dosomething2(B b){
System.out.println("Inside b dosomething2");
}
}
該注釋在技術上是可選的,但是它是如此有用,以至於在實踐中人們將其視為強制性的。
是方法覆蓋
為什么Java不像在運行時那樣調用B中定義的方法,它知道a2是B的對象。
因為dosomething2
在A
和dosomething2
中B
有不同的簽名。
您沒有在B
重寫dosomething2
。 關於動態調度, B
中的dosomething2
是一種新方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.