2012-05-05 123 views
0

在靜態方法重載的情況下..我有下面的代碼開發了這個關於靜態方法覆蓋

class Ab { 
    static void getF() { 
     System.out.println("I am saral"); 
    } 
} 

class Ham extends Ab { 
    static void getF() { 
     System.out.println("I am saral saxena"); 
    } 
    public static void main(String[] args) { 
     // Ham h = new Ham(); 
     // h.getF(); //Ham 
     Ab a = new Ham(); 
     a.getF(); // Ab class 
    } 
} 

現在我的查詢是靜態方法重載的情況下,當我使用在這個階段多態行爲,Ab a = new Ham();我仍然得到類Ab的方法getF();,請告知。

回答

5

不能覆蓋靜態方法。

靜態方法屬於類。你可以撥打Ab.getF()Ham.getF() - 你選擇了你的代碼。

在類層次結構中命名靜態方法不會有什麼影響(除了可能導致程序員混淆)。靜態方法是屬於類的代碼的浮動位,而不是實例。只有實例方法對重寫非常敏感。

由於這個原因,在實例上調用靜態方法的風格很差(因爲它使得該方法看起來像是一個實例方法)。它在語言中是允許的,但會導致程序員混淆,因此會導致錯誤,特別是如果靜態方法的名稱類似於實例方法 - 例如發現名爲setName(String)的方法是一種靜態方法,則可能是合理的殺人理由。

+0

@ Bohemian..yeah that這個概念是靜態方法隱藏不被覆蓋 – dghtr

+1

否 - 它們不是隱藏的(或被稱爲* shadowed)。靜態方法沒有這樣的概念。 – Bohemian

+0

謝謝,請您詳細解釋一下。 – dghtr

4

在編譯時,如調用該變量聲明爲,而不是實際實例類,所以a.getF();將導致是Ab.getF();而不是Ham.getF();類是通過實例調用靜態方法編譯。

這是一個非常不好的做法,通常用實例調用靜態方法而不是類名。 (我覺得最好的例子就是在thread實例調用Thread.sleep(),假設它會導致實例線程睡眠,但實際上當前線程)

0

覆蓋靜態函數是不可能和無用的(我避免使用術語方法,因爲方法涉及到對象)。

當有需要調用取決於對象的類別不同的​​靜態功能,做這種方式

class Ab { 
private static void getF() { 
    System.out.println("I am saral"); 
} 
public void doit() { 
    getF(); 
} 
} 
class Ham extends Ab { 
private static void getF() { 
    System.out.println("I am saral saxena"); 
} 
@Override 
public void doit() 
{ 
    getF(); 
} 
public static void main(String[] args) { 
    Ab a = new Ham(); 
    a.doit(); // Ham class 
} 

}

順便說一句,使用得到一個函數返回void很奇怪

0

第一件事是你不能調用派生類中具有名稱和簽名的靜態方法與在基類中一個重寫的情況。

這是因爲在重載的情況下,編譯器不會生成函數調用的字節代碼,因爲實際的方法將被調用在運行時根據 來解析參考變量的多態行爲。

覆蓋實際上是由編譯器的這種動態行爲定義的(而不是基類和具有相同signatured方法的子類,這些只是覆蓋的前提條件)。

靜態方法是類的實體,並因此結合到參考變量,而不是運行時間對象,從而如果通過將其稱爲方法調用在僅編譯時(基於參考變量,或類名的類型解決。

同樣,如果你有公共實例變量或靜態變量在超類和子類中都具有相同的名稱和類型,那麼將選擇具有變量類型的變量而不是運行時對象。