2013-08-04 88 views
1

所以我知道在Java中,當你有你應該與格式ClassName.method()調用它,而不是使用相同的結構,你會爲實例方法,即靜態方法:但是,如果你在Java中繼承靜態方法?

ClassName myObject = new ClassName(); 
myObject.method(); 

要這樣做它仍然是有效的代碼,並會工作。比方說,我決定這樣做,其中有問題的方法是靜態的,並且具有以下設置:

public SuperClass { 
    public static int foo(int x) { 
     return x; 
    } 
} 

public SubClass extends SuperClass { 
    public static int foo(int x) { // Overriding foo() in SuperClass 
     return x + 1; 
    } 
} 

public MyDriver { 
    public static void main(String[] args) { 
     SuperClass myObject = new SubClass(); // Upcasting. 
     System.out.println(myObject.foo(5)); // This should polymorphically print 6 
    } 
} 

什麼打印出屏幕上,但是,5而不是6.爲什麼?

回答

5

靜態方法僅適用於它們在其中定義的類,並且它們不能被覆蓋。

當你調用myObject.foo(5),您呼叫在現實SuperClass.foo(5),因爲你宣佈myObjectSuperClass,無論你是實例爲一體。

正確的方法調用靜態方法是直接從它被聲明在類調用它,所以如果你想叫SubClass.foo(),你必須從顯式聲明的​​實例調用它(意味着沒有上傳),或者你需要像這樣調用SubClass.foo()

簡單的答案是,從實例調用靜態方法的計算結果是從聲明的類型調用那些沒有實例而不是實例類型的相同方法。

我不確定這一點,但如果將代碼編譯爲字節碼時,我不會感到驚訝,實例靜態方法調用實際上會編譯爲直接調用聲明的類型。

編輯:upvote把我的注意力帶回了這一點,我清理了解釋,使其更加清晰,並修復了我的一些可以忽略的語法錯誤。我希望這有助於未來的讀者。

1

靜態方法不依賴於實例,它們屬於類而只屬於類,事實上,如果你有一個靜態方法,你將總是訪問一個唯一的實例。

myObject.foo(5) 

只是一個快捷方式,你真正做的是

SuperClass.foo(5) 
+0

這不是真的只有一個實例,它是每個虛擬機一個,如果你有一個以上的虛擬機,你可能有多個實例。 – luisZavaleta

+2

+1,但取決於ClassLoader體系結構,它甚至可能會超過每個JVM一個;例如OSGi。 – earcam

1

使用一個類的實例來調用這個類的靜態方法是你應該避免,因爲它可能會導致混亂。如果您需要多態調用任何方法,請將其設爲實例方法。你不能多態地調用靜態方法。 SuperClass調用被調用的原因是因爲這是編譯時myObject的明顯類。這種效果也可以被看作在以下情形:

public void doSomething(SuperClass param) { 
    System.out.println("SuperClass"); 
} 

public void doSomething(SubClass param) { 
    System.out.println("SubClass"); 
} 

public void test() { 
    SuperClass myObject = new SubClass(); 
    doSomething(myObject); 
} 

如果測試()被調用,SuperClass將被打印。

0

靜態方法被JVM視爲全局對象,它們根本沒有綁定到對象實例。順便說一句,你只能重載靜態方法,但你不能重寫。因此請檢查"Oracle Documentation for Overriding and Hiding Documents"

定義一個方法具有相同簽名作爲父類的方法:

--------------------------- --------------超類的實例方法超類靜態方法      
子類的實例方法            重寫                                                                         產生編譯時間錯誤
子類靜態方法                        產生編譯時間錯誤     隱藏