靜態方法的繼承問題
最近看到靜態方法的繼承問題,看到網上的說法,自己還是有點不太理解,靜態方法不是不可以被繼承,同樣的,靜態方法也可以被繼承,但是子類對於靜態方法的“重寫”是通過隱藏父類的靜態方法來實現的,所以靜態方法可以被繼承,但是不能被重寫,因此不能實現多態。
先看父類實例代碼:
package test; public class StaticMethodExtendTestParent { public static void MethodA(){ System.out.println("Parent MethodA!"); }public void MethodB(){ System.out.println("Parent MethodB Call MethodA!"); MethodA(); } public void MethodC(){ System.out.println("Parent MethodC!"); } public void MethodD(){ System.out.println("Parent MethodD Call MethodC!"); MethodC(); } }
在子類中,“重寫”了方法A和方法C:
package test; public class StaticMethodExtendTest extends StaticMethodExtendTestParent{ public static void MethodA(){ System.out.println("Child MethodA!"); } public void MethodC(){ System.out.println("Child MethodC!"); } }
基於以上的情況我們考慮多中情形:
(1)當我們直接用子類對象調用方法A和方法C
public static void main(String[] args) { StaticMethodExtendTest child = new StaticMethodExtendTest(); child.MethodA(); child.MethodC(); }
輸出:
和我們平時的理解一樣,調用的都是子類的A和C方法,這樣看起來靜態方法和非靜態方法是一樣的,好像都將父類的方法進行了重寫覆蓋。
(2)父類對象接受子類對象向上轉型調用方法A和方法C
public static void main(String[] args) { StaticMethodExtendTestParent parent = new StaticMethodExtendTest(); parent.MethodA(); parent.MethodC(); }
輸出:
這裏我們看到方法C的輸出很好的體現了java的多態性質,但是方法A仍然調用的是父類的方法A,這也就是我們前面說的,對於父類的靜態方法,子類的“重寫”只是將父類的方法隱藏。對於方法C,程序只有在程序運行時才能確定調用的到底是哪個類中實現的方法,有可能是基類的方法,有可能是基類的方法,這取決於StaticMethodExtendTestParent的實例對象接受的是哪一種類(StaticMethodExtendTestParent基類還是子類)。但是對於方法A,在實例對象的類型定義後就已經確定了,如果實例對象為StaticMethodExtendTestParent類型,那麽無論對象實際接受的是哪一個子類的對象,方法A的調用始終是StaticMethodExtendTestParent的A方法。在上述實例中如果子類沒有MethodA方法,那麽子類對象對A方法的調用都將調用父類的A方法,所以靜態方法可以被繼承,但是不能被重寫,無法實現多態。
(3)通過子類對象在父類的方法中調用被子類“重寫”的方法
public static void main(String[] args) { StaticMethodExtendTest child = new StaticMethodExtendTest(); child.MethodA(); child.MethodB(); child.MethodC(); child.MethodD(); System.out.println("====================="); StaticMethodExtendTestParent parent = new StaticMethodExtendTest(); parent.MethodA(); parent.MethodB(); parent.MethodC(); parent.MethodD(); }
測試結果:
這裏直接測試了兩種情況,可以看出無論子類有沒有向上轉型,當調用父類方法時B,B中有對靜態方法A的調用,都是直接調用的父類的靜態方法A,方法D和C的調用則是我們熟知的多態的情形。
靜態方法的繼承問題