首先來(lái)看看以下程序?qū)?huì)打印出什么:
class Basenji extends Dog {
public static void bark() { }
}
public class Bark {
public static void main(String args[]) {
Dog woofer = new Dog();
Dog nipper = new Basenji();
woofer.bark();
nipper.bark();
}
}
問(wèn)題在于bark是一個(gè)靜態(tài)方法,而對(duì)靜態(tài)方法的調(diào)用不存在任何動(dòng)態(tài)的分派機(jī)制[JLS 15.12.4.4]。當(dāng)一個(gè)程序調(diào)用了一個(gè)靜態(tài)方法時(shí),要被調(diào)用的方法都是在編譯時(shí)刻被選定的,而這種選定是基于修飾符的編譯期類型而做出的,修飾符的編譯期類型就是我們給出的方法調(diào)用表達(dá)式中圓點(diǎn)左邊部分的名字。在本案中,兩個(gè)方法調(diào)用的修飾符分別是變量woofer和nipper,它們都被聲明為Dog類型。因?yàn)樗鼈兙哂邢嗤木幾g期類型,所以編譯器使得它們調(diào)用的是相同的方法:Dog.bark。這也就解釋了為什么程序打印出woof woof。盡管nipper的運(yùn)行期類型是Basenji,但是編譯器只會(huì)考慮其編譯器類型。
要訂正這個(gè)程序,直接從兩個(gè)bark方法定義中移除掉static修飾符即可。這樣,Basenji中的bark方法將覆寫(xiě)而不是隱藏Dog中的bark方法,而該程序也將會(huì)打印出woof,而不是woof woof。通過(guò)覆寫(xiě),你可以獲得動(dòng)態(tài)的分派;而通過(guò)隱藏,你卻得不到這種特性。
新聞熱點(diǎn)
疑難解答
圖片精選