8 回答

TA貢獻(xiàn)1845條經(jīng)驗(yàn) 獲得超8個(gè)贊
1、java類(lèi)是運(yùn)行在jvm(java虛擬機(jī))中的,所以這里的執(zhí)行效果取決于 jvm規(guī)范 對(duì)于方法執(zhí)行效果的定義
2、jvm在執(zhí)行一個(gè)方法的時(shí)候,有以下知識(shí)點(diǎn)
2.1.?執(zhí)行方法前,虛擬機(jī)讀取?class文件至內(nèi)存,并生成對(duì)應(yīng)的?Class?對(duì)象放在靜態(tài)區(qū)中。跟你這個(gè)問(wèn)題比較相關(guān)的一點(diǎn)是,虛擬機(jī)會(huì)針對(duì)每個(gè)類(lèi)的所有方法,形成一個(gè)虛函數(shù)表,以實(shí)現(xiàn)運(yùn)行(調(diào)用)時(shí)的快速查找。 2.2.?當(dāng)加載一個(gè)具有繼承體系的類(lèi)時(shí),會(huì)先加載父類(lèi),先調(diào)用父類(lèi)的構(gòu)造函數(shù),在執(zhí)行子類(lèi)的構(gòu)造函數(shù)。虛函數(shù)表的生成同樣也具有這種先后順序。子類(lèi)會(huì)覆蓋同名的父類(lèi)虛方法表中同名同可見(jiàn)性方法。 2.3.?具有繼承層次的類(lèi)的虛方法表查找,默認(rèn)先查找子類(lèi)虛方法表,找不到才會(huì)找父類(lèi)的。
結(jié)合題主的例子,當(dāng) TestMain 中,執(zhí)行到b.attack();
方法時(shí),默認(rèn)讀取的自然是 bee類(lèi)的虛函數(shù)表,由2.2可知:
第一個(gè)fly:bee.attack()——>?bee.move() 第二個(gè)fly:bee.attack()——>?bee.move()——>?inset.attack()——>?bee.move() //之所以這里會(huì)由?insect.attack()?里執(zhí)行到?bee.move()?就是前面說(shuō)得,insect?作為實(shí)例化?bee?類(lèi)順帶生成的內(nèi)置父類(lèi)對(duì)象,默認(rèn)讀取虛方法表會(huì)優(yōu)先從子類(lèi)開(kāi)始查找
題外話,題主可以思考一下為什么java要這么設(shè)計(jì)虛方法表的調(diào)用邏輯,與多態(tài)的實(shí)現(xiàn)又有什么關(guān)系?

TA貢獻(xiàn)1909條經(jīng)驗(yàn) 獲得超7個(gè)贊
因?yàn)?code>Bee類(lèi)繼承了Insect
類(lèi),所以Bee
類(lèi)調(diào)用方法會(huì)優(yōu)先到當(dāng)前類(lèi)中找尋,沒(méi)有才會(huì)調(diào)用父類(lèi)的方法,由于Bee
類(lèi)自己存在move
方法的,所以就不會(huì)調(diào)用父類(lèi)的move
方法,而為什么會(huì)調(diào)用父類(lèi)的attack
方法是因?yàn)槟阌昧?code>super,如果你用super.move

TA貢獻(xiàn)1752條經(jīng)驗(yàn) 獲得超4個(gè)贊
題主可能糾結(jié)在于
@Override
public void attack() {
move();
//這里super會(huì)調(diào)用夫類(lèi)Insect.attack方法
super.attack();
//System.out.println("Attack");
}
都已經(jīng)執(zhí)行至父類(lèi)的attack()方法中了,為什么還會(huì)去調(diào)用子類(lèi)的move()方法呢?
對(duì)此,不知道該怎么從理論上進(jìn)行闡述題主的疑惑,只是知道,當(dāng)前類(lèi)有的方法就執(zhí)行,當(dāng)前類(lèi)沒(méi)有或者明確用super關(guān)鍵字指明的,才會(huì)執(zhí)行父類(lèi)方法

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個(gè)贊
因?yàn)閙ove方法已經(jīng)被子類(lèi)方法重寫(xiě)覆蓋了呀
你可能和隱藏字段的概念混淆了
重寫(xiě)方法就是覆蓋了,用的只會(huì)是子類(lèi)中的新方法
重寫(xiě)字段只是隱藏了,super調(diào)用基類(lèi)的方法里還是用的基類(lèi)原來(lái)的字段

TA貢獻(xiàn)2036條經(jīng)驗(yàn) 獲得超8個(gè)贊
指令中call
與callvirt
調(diào)用方法的區(qū)別,callvirt
會(huì)優(yōu)先尋找子類(lèi)中重寫(xiě)的方法,call
則直接調(diào)用父類(lèi)聲明的方法。

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個(gè)贊
看到題主的這個(gè)問(wèn)題,我想對(duì)你說(shuō)下,在開(kāi)發(fā)行業(yè),基礎(chǔ)很重要,基礎(chǔ)好才能走更遠(yuǎn),否則寫(xiě)代碼知其一不知其二,本人現(xiàn)在前端開(kāi)發(fā)一枚,以前搞過(guò)安卓、PHP。
添加回答
舉報(bào)