如果你認(rèn)為重寫(xiě)只是在子類(lèi)中簡(jiǎn)單的替換了一個(gè)方法,你就很容易認(rèn)為static 方法也能
被重寫(xiě)。事實(shí)上,我有很多包含人們舉例指明static 方法能被重寫(xiě)的代碼的郵件。然而,這
些并沒(méi)有考慮方法重寫(xiě)在運(yùn)行時(shí)決定哪個(gè)版本的方法被調(diào)用的細(xì)節(jié)問(wèn)題。下面的代碼似乎表
明static 方法是怎樣被重寫(xiě)的。
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");
???}
}
如果你編譯并運(yùn)行這段代碼,你會(huì)發(fā)現(xiàn)輸出文本Cravengib.amethod,這似乎很好的指
明了重寫(xiě)。然而,對(duì)于重寫(xiě),還有相對(duì)于在子類(lèi)中使用一個(gè)方法簡(jiǎn)單替換另一個(gè)方法更多的
東西。還有運(yùn)行時(shí)決定的方法基于引用的類(lèi)的類(lèi)型的問(wèn)題,這可以通過(guò)制造正在被實(shí)例化的
類(lèi)的引用類(lèi)型(實(shí)例初始化語(yǔ)句的左半部分)來(lái)說(shuō)明。
在上面的例子中,因?yàn)槊纸衋method 的方法與類(lèi)發(fā)生了關(guān)聯(lián),而不是與特定的類(lèi)的實(shí)
例相關(guān)聯(lián),它不在乎什么類(lèi)型的類(lèi)正在創(chuàng)建它,而僅僅在意引用的類(lèi)型。因此,如果你在調(diào)
用amethod 前改變一下這一行,
Base cg= new Cravengib()
你就會(huì)發(fā)現(xiàn)當(dāng)你運(yùn)行程序時(shí),你會(huì)得到輸出:Base.amethod
cg 是一個(gè)類(lèi)Cravengib 在內(nèi)存中的一個(gè)Base 類(lèi)型的實(shí)例的引用(或者指針)。如果一個(gè)static
方法被調(diào)用了,JVM 不會(huì)檢查什么類(lèi)型正在指向它,它只會(huì)調(diào)用跟Base 類(lèi)相關(guān)聯(lián)的方法的
實(shí)例。
與上面的情況相對(duì)比:當(dāng)一個(gè)方法被重寫(xiě)時(shí),JVM 檢查通過(guò)引用正在指向的類(lèi)的類(lèi)型,
并調(diào)用此類(lèi)型相關(guān)的方法。可以結(jié)束這個(gè)例子了,如果你將兩個(gè)版本的amethod 方法改變?yōu)?br />非static,并依然創(chuàng)建類(lèi):
Base cg= new Cravengib()
編譯并運(yùn)行上述代碼,你會(huì)發(fā)現(xiàn)amethod 已經(jīng)被重寫(xiě)了,并且輸出Cravengib.amethod。