覆蓋與隱藏

1.根據Java Language Specification (Version 3) 8.4.8 的描述,子類在繼承父類時,對於方法而言,存在兩種關係:
A. override 即覆蓋,這是對實例方法(instance method)而言的;子類與父類中形構相同的方法(原文中是 subsignature,它的範圍比“形構相同”要大,請參考原文)會override 父類中的那個方法。

B. hide 即隱藏,這是對類方法(class method)即static 方法而言的。如果子類中定義了靜態方法,則它會隱藏父類中形構相同的(原文中是 subsignature,它的範圍比“形構相同要”大,請參考原文)所有方法,但如果隱藏了父類中的實例方法,則會編譯報錯。

2.根據上面的規範:
“override 覆蓋”的前提是 實例方法,只有實例方法在繼承時纔會出現override情況。
如果是static方法,在繼承時出現的現象根本就不能用“override”這個詞描述,如果static方法在父類和子類中形構一致,則被成爲 hide(隱藏)。

3.因爲static方法是類方法,實現時是靜態綁定的(引用“JAVA 核心技術 卷1 第六版”中149頁內容“private、static、final”修飾的方法是靜態綁定的。其他的方法在運行時動態綁定。“interhanchi”所說的“static和final方法外都是後期綁定”並不精確),只與類相關,不會有多態性。 從編程的角度看,效果好像是“static方法不能被覆蓋”;

4.從術語上看,“static方法能否被覆蓋”這種說法本身就是錯誤的,因爲“覆蓋”定義的前提和基礎是實例方法。

5.結論: 子類中的static方法會隱藏父類中形構相同的static方法。

附:關於Java 的隱藏 機制,幾本經典的書都沒有詳細說明。準備寫一個這方面的材料,請有興趣的朋友關注 http://blog.csdn.net/jidongxx。


3.在進行引用變量的類型轉換時,會受到各種限制。而且在通過引用變量訪問它所引用的實例的靜態屬性、靜態方法、實例屬性、實例方法,以及從父類中繼承的方法和屬性時,Java虛擬機會採用不同的綁定機制。

4.成員變量、靜態方法按照引用變量聲明的類型靜態綁定;實例方法按照引用變量引用的實例動態綁定。
例如,對於以下這段代碼:
Fathers f=new Sons();
System.out.println(“f.var=”+f.var);
System.out.println(“f.staticVar=”+f.staticVar);
f.method();
f.staticMethod();
運行時將會輸出如下結果:
f.var=FatherVar
f.staticVar=StaticFaterVar
Son method
Static Father method


class Fathers{
String var="FatherVar";
static String staticVar="StaticFatherVar";
void method(){System.out.println("Father method");}
static void staticMethod(){System.out.println("Static Father method");}
}

class Sons extends Fathers{
String var="SonVar";
static String staticVar="StaticSonVar";

void method(){System.out.println("Son method");}
static void staticMethod(){System.out.println("Static Son method");}

String sonVar=null;
void sonMethod(){}
}
發佈了41 篇原創文章 · 獲贊 2 · 訪問量 2978
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章