簡體   English   中英

是方法重寫還是重載?

[英]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的對象。

因為dosomething2Adosomething2B有不同的簽名。
您沒有在B重寫dosomething2 關於動態調度, B中的dosomething2是一種新方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM