如果你認為重寫只是在子類中簡單的替換了一個方法,你就很容易認為static 方法也能
被重寫。事實上,我有很多包含人們舉例指明static 方法能被重寫的代碼的郵件。然而,這
些并沒有考慮方法重寫在運行時決定哪個版本的方法被調用的細節問題。下面的代碼似乎表
明static 方法是怎樣被重寫的。
class Base{
???static void amethod(){
???System.out.println("Base.amethod");
???}
}
public class Cravengib extends Base{
???public static void main(String arg[]){
??????Cravengib cg = new Cravengib();
??????cg.amethod();
???}
???static void amethod(){
??????System.out.println("Cravengib.amethod");
???}
}
如果你編譯并運行這段代碼,你會發現輸出文本Cravengib.amethod,這似乎很好的指
明了重寫。然而,對于重寫,還有相對于在子類中使用一個方法簡單替換另一個方法更多的
東西。還有運行時決定的方法基于引用的類的類型的問題,這可以通過制造正在被實例化的
類的引用類型(實例初始化語句的左半部分)來說明。
在上面的例子中,因為名字叫amethod 的方法與類發生了關聯,而不是與特定的類的實
例相關聯,它不在乎什么類型的類正在創建它,而僅僅在意引用的類型。因此,如果你在調
用amethod 前改變一下這一行,
Base cg= new Cravengib()
你就會發現當你運行程序時,你會得到輸出:Base.amethod
cg 是一個類Cravengib 在內存中的一個Base 類型的實例的引用(或者指針)。如果一個static
方法被調用了,JVM 不會檢查什么類型正在指向它,它只會調用跟Base 類相關聯的方法的
實例。
與上面的情況相對比:當一個方法被重寫時,JVM 檢查通過引用正在指向的類的類型,
并調用此類型相關的方法。可以結束這個例子了,如果你將兩個版本的amethod 方法改變為
非static,并依然創建類:
Base cg= new Cravengib()
編譯并運行上述代碼,你會發現amethod 已經被重寫了,并且輸出Cravengib.amethod。