1. 程式人生 > >靜態方法的繼承問題

靜態方法的繼承問題

test 理解 new .cn com pan system println cme

  最近看到靜態方法的繼承問題,看到網上的說法,自己還是有點不太理解,靜態方法不是不可以被繼承,同樣的,靜態方法也可以被繼承,但是子類對於靜態方法的“重寫”是通過隱藏父類的靜態方法來實現的,所以靜態方法可以被繼承,但是不能被重寫,因此不能實現多態。

  先看父類實例代碼:

  

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的調用則是我們熟知的多態的情形。

  

靜態方法的繼承問題