[英]Inheriting static methods in Java?
所以我知道在Java中,當您有一個靜態方法時,應該以ClassName.method()
格式調用它,而不是使用與實例方法相同的結構,即:
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。為什么?
靜態方法僅適用於定義它們的類,並且不能覆蓋它們。
調用myObject.foo(5)
,實際上是在調用SuperClass.foo(5)
,因為您將myObject
聲明為SuperClass
,而不管是否將其實例化為一個。
調用靜態方法的正確方法是直接從聲明其的類中調用它,因此,如果要調用SubClass.foo()
,則必須從一個顯式聲明的SubClass
實例(意味着沒有向上轉換)中調用它,或者您需要像這樣調用SubClass.foo()
。
簡單的答案是,從實例調用靜態方法的評估結果是從沒有實例而不是實例類型的聲明類型調用那些相同的方法。
我不確定,但是如果將代碼編譯成字節碼,實例靜態方法調用實際上將被編譯成對聲明類型的直接調用,我不會感到驚訝。
編輯:贊成票使我的注意力回到了這一點上,我整理了說明以使其更清楚,並糾正了一些可忽略的語法錯誤。 希望對以后的讀者有所幫助。
靜態方法不依賴於實例,它們屬於類並且僅屬於類,實際上,如果您具有靜態方法,則始終將始終訪問一個唯一的實例。
myObject.foo(5)
只是捷徑,你真正在做的是
SuperClass.foo(5)
應該避免使用類的實例來調用該類的靜態方法,因為這會引起混亂。 如果您需要多態調用任何方法,請使其成為實例方法。 您不能多態調用靜態方法。 調用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);
}
如果調用test(),則將打印SuperClass
。
靜態方法被JVM視為全局方法,它們根本沒有綁定到對象實例。 順便說一句,您只能重載靜態方法,但不能覆蓋。 因此,請檢查“用於覆蓋和隱藏文檔的Oracle文檔” 。
定義與超類的方法具有相同簽名的方法:
----------------------------------------- 超類實例方法 超類靜態方法
子類實例方法 重寫 產生編譯時錯誤
子類的靜態方法 生成一個編譯時錯誤 隱藏
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.