1. 程式人生 > >Java過載、重寫、覆蓋、隱藏的總結

Java過載、重寫、覆蓋、隱藏的總結

過載Overloading

發生要素如下:

1. 在同一作用範圍內(同一個類,同一個介面)

2. 方法名必定相同

3. 形參組成不同(型別、個數均不相同 or 個數相同但型別不同 or 型別相同個數不同)

錯誤的認識:

1. 方法名相同,形參組成完全相同,返回型別不同也算過載(報錯)

2. 有abstract修飾才算過載(無所謂啊,修飾符惹誰了?)

abstract class AbstractBase {
    abstract void add();  
    abstract void add(int a);  //OK 
    void add(String b){} //OK
    int add(String b){} // NO!!!編譯不通過
    protected void add(int a,int b){}
}

覆蓋/重寫/覆寫(一個意思!)(Overriding/Overwrite)

發生要素如下:

1. 不同作用範圍內(繼承別的類,實現介面)

2. 方法名相同(廢話!)

3. 形參組成相同(型別、個數均相同)

4. 返回型別相同

個人理解:

1. 既然是覆蓋,要完全蓋住,學的像點,所以方法的外表要看上去一樣嘛。

2. 實現介面方法,也可稱為覆蓋,畢竟是把空的方法體覆蓋為具體的程式碼了。想想也是,實現介面的時候IDE是不是為我們自動加上了@Override註解?這個在JDK6之前的版本可不行,寫這個註解是會報錯的。(懷念起在老東家運維JDK1.5專案的時光)

要注意的地方:派生方法不能丟擲比基類方法範圍更廣的異常(速記:孩子不能闖比父母更大的禍),

                         錯誤範例:基類方法throws IOException,派生方法卻throws Exception。

                         派生方法不能有比基類方法更大的訪問度(速記:孩子不能比父母更能顯擺),

                         錯誤範例:基類方法是protected,派生方法卻是public。

隱藏Hiding

發生要素如下:

1. 同覆蓋的1.2.3.4條件(必要)

2. 僅發生在靜態方法上

要點:

隱藏不需要@Override註解修飾,加上會報錯。且派生方法的可丟擲異常範圍和可訪問範圍的約束與覆蓋相同(不能拋更多異常,不能有更廣的訪問許可權)。

在jls11文件中,隱藏註明為 by Class Methods,而覆蓋則是by Instance Methods,這個很好理解,靜態的成員方法就是屬於這個類的,隱藏也可以叫類的方法的覆蓋。

個人理解:靜態方法是和類繫結到一起的,那麼在例項化的時候,用的誰的型別的引用,那麼call到的方法就是誰的實現,也許說的不恰當,請看下例:

       class Super {
           static String greeting() { return "Goodnight"; }
           String name() { return "Richard"; }
       }
       class Sub extends Super {
           static String greeting() { return "Hello"; }
           String name() { return "Kick"; }
       }
       class Test {
           public static void main(String[] args) {
               Super s = new Sub();  
               System.out.println(s.greeting() + ", " + s.name());
               //輸出:Goodnight, Kick
               Sub s2 = new Sub();
               System.out.println(s2.greeting() + ", " + s.name());
               //輸出:Hello, Kick
           } 

}

由於s的型別是Super,所以greeting()執行的是Super的實現,但是name()是正常的覆蓋,好比派生類沒有重寫greeting()一樣(派生類乾的事兒被藏起來了)。但是s2 call到的就是Sub的實現了,符合常規的思路。

 

  本文參考:jsl11文件