原文地址http://www.cnblogs.com/111testing/p/6880831.html
Java多態的三個必要條件:
1、 繼承
2、 子類重寫父類方法
3、 父類引用指向子類對象
然後看一個例子
輸出結果爲:
給出結論:Father c = new Child() 在c的眼裏只能看到 child 裏面的 father 屬性!
當滿Java多態的三個條件時,可以發現c.eat()調用的實際上是子類的eat(是因爲子類重寫覆蓋了父類方法),
但c.age調用的還是父類的age(屬性/變量不存在重寫和覆蓋),而c.play()則不會通過編譯。
但是在java的引用中Father不但指定了c以何種方式訪問內存,也規定了能夠訪問內存空間的大小。
我們看Father實例對象的大小是佔兩行,但Child實例對象佔三行(這裏就是簡單量化一下)。
所以雖然c指向的是Child實例對象,但是前面有Father修飾它,它也只能訪問兩行的數據,也就是說c根本訪問不到Child類中的age!!!只能訪問到Father類的age,所以輸出40
我們看到Parent的方法表佔三行,Child的方法表佔4行,c雖然指向了Child類的實例對象,
而對象中也有指針指向Child類的方法表,但是由於c受到了Father的修飾,通過c也只能訪問到Child方法表中前3行的內容!!!!
然而前面說過,在方法表的形成過程中,子類重寫的方法會覆蓋掉表中原來的數據,也就是Child類的方法表的第三行是指向Child.eat的引用,
而不是指向Parent.eat(因爲方法表產生了覆蓋),所以c訪問到的是Child.eat。也就是子類的方法!!!這種情況下,c是沒有辦法直接訪問到父類的eat方法的。