從JVM看Java語言特性(三) 多態(tài)

1. 多態(tài)

多態(tài)這種特性簡(jiǎn)而言之就是用父類型別的引用指向其子類的實(shí)例览效,然后通過父類的方法調(diào)用實(shí)際子類的成員函數(shù). 先拋結(jié)論: 個(gè)人理解的所謂多態(tài), 本質(zhì)上就是重寫機(jī)制加上向上轉(zhuǎn)型, 重寫就是說子類的同名同參數(shù)的方法可以覆蓋父類的方法, 子類的向上轉(zhuǎn)型消除了多余方法, 就成了多態(tài).

先給出一個(gè)多態(tài)非常簡(jiǎn)單的例子:

Father father = new Child();

這里例子中我們new一個(gè)Child實(shí)例將它丟給father這個(gè)接口, 當(dāng)調(diào)用沒有被重寫的方法時(shí), JVM執(zhí)行父類方法, 當(dāng)調(diào)用被Child重寫過的方法時(shí), 則執(zhí)行子類方法.

2. 多態(tài)的實(shí)現(xiàn)

首先先明確一件事, 多態(tài)=重寫+向上轉(zhuǎn)型, 所以下面關(guān)于的多態(tài)的原理其實(shí)就是重寫的原理.

對(duì)C++了解的同學(xué)應(yīng)該知道C++里面有虛函數(shù)這個(gè)東西, C++為了實(shí)現(xiàn)多態(tài), 在就在實(shí)例對(duì)象里面內(nèi)嵌了虛函數(shù)表vtable, 這個(gè)虛函數(shù)表, 其實(shí)就是一個(gè)存儲(chǔ)了一堆方法指針的表, 來指定調(diào)用的函數(shù), 實(shí)現(xiàn)方法分派. 如果沒有virtual關(guān)鍵字, 那么這個(gè)函數(shù)會(huì)在vtable中保存兩份, 父類的函數(shù)和子類的函數(shù)都會(huì)保存. 用父類引用調(diào)用父類函數(shù), 子類引用調(diào)用子類函數(shù).

Java的vtable和C++大同小異, 最大的區(qū)別在于Java的vtable是在類加載時(shí)動(dòng)態(tài)構(gòu)建的, 大致的邏輯是這樣的:

  1. 一開始繼承類的vtable中的指針完全指向父類的方法, 也就是說一開始子類的vtable就是父類的vtable
  2. JVM遍歷子類的所有方法, 找到所有被public或protected關(guān)鍵詞修飾, 并且沒有被static或final修飾的方法, 判斷其方法簽名是否與父類一致, 如果一致說明發(fā)生了重寫, 那么將子類的原本指向父類的方法指針修改為指向自己的方法.
  3. 如果找出來的方法簽名不一致, 說明子類自己定義了新方法, 那么就把vtable長(zhǎng)度增加1, 并將指針指向新方法

經(jīng)過以上步驟, vtable構(gòu)建完成, 這張表里面分別包含了父類方法(沒重寫的)和子類方法(重寫的), 剩下的事情就順理成章了, 程序在調(diào)用父類引用方法的時(shí)候, JVM會(huì)通過vtable里的指針來調(diào)用方法, 這就是多態(tài).

3. 多態(tài)的好處

多態(tài)可以實(shí)現(xiàn)接口復(fù)用, 隱藏實(shí)現(xiàn)細(xì)節(jié), 降低代碼的復(fù)雜度. 策略模式就是個(gè)最簡(jiǎn)單的例子, 策略模式讓一個(gè)接口實(shí)現(xiàn)多種類, 但是反映在代碼里面真實(shí)使用的就是父類引用Father, 這樣不僅封裝了內(nèi)部細(xì)節(jié), 使代碼更簡(jiǎn)潔. 還增加了可維護(hù)性, 在需要這個(gè)接口或者父類實(shí)現(xiàn)不同功能的時(shí)候只需要將不同的子類向上轉(zhuǎn)型為Father就行了, 簡(jiǎn)潔明了.

這種簡(jiǎn)化分層其實(shí)就是解耦的思想, 解耦的最終目的就是為了使不同功能的代碼放在不同地方, 所謂高內(nèi)聚低耦合, 從而實(shí)現(xiàn)強(qiáng)大的可維護(hù)性, 提升效率. 具體來看, 不論是多態(tài)也好, 依賴注入也好, XML配置也好, 最終目的就是將所有配置和賦值放在一起, 而把核心代碼放在另一個(gè)地方, 當(dāng)需要修改時(shí), 只需要修改配置文件或者實(shí)現(xiàn)不同的接口就可以實(shí)現(xiàn)不同功能

接口復(fù)用讓模塊化或者分層變得簡(jiǎn)單, 在寫一個(gè)大型項(xiàng)目的時(shí)候, 一般來說都需要很多模塊互相調(diào)用. 作為一個(gè)模塊的開發(fā)者我要是不想經(jīng)常讓別人修改代碼, 我就得保持自己寫的接口不變, 來修改下面的實(shí)現(xiàn)類.

進(jìn)一步思考, 這個(gè)時(shí)候想想什么叫做控制反轉(zhuǎn)就顯而易見了, 目的還是為了進(jìn)一步降低耦合度. 對(duì)于一個(gè)組件來說, 開發(fā)者甚至不希望使用者自己來實(shí)現(xiàn)接口, 而是讓使用者加個(gè)注解, 我自己來幫你實(shí)現(xiàn), 優(yōu)點(diǎn)當(dāng)然是顯而易見的, 組件的實(shí)現(xiàn)類甚至連名字都可以自由更換.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昌犹,一起剝皮案震驚了整個(gè)濱河市柴底,隨后出現(xiàn)的幾起案子聊训,更是在濱河造成了極大的恐慌绿饵,老刑警劉巖灿里,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凿叠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡昆淡,警方通過查閱死者的電腦和手機(jī)锰瘸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昂灵,“玉大人避凝,你說我怎么就攤上這事≌2梗” “怎么了管削?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)撑螺。 經(jīng)常有香客問我含思,道長(zhǎng),這世上最難降的妖魔是什么甘晤? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任含潘,我火速辦了婚禮,結(jié)果婚禮上线婚,老公的妹妹穿的比我還像新娘遏弱。我一直安慰自己,他們只是感情好塞弊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布漱逸。 她就那樣靜靜地躺著泪姨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饰抒。 梳的紋絲不亂的頭發(fā)上肮砾,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音循集,去河邊找鬼唇敞。 笑死蔗草,一個(gè)胖子當(dāng)著我的面吹牛咒彤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咒精,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼镶柱,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了模叙?” 一聲冷哼從身側(cè)響起歇拆,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎范咨,沒想到半個(gè)月后故觅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渠啊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年输吏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片替蛉。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贯溅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躲查,到底是詐尸還是另有隱情它浅,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布镣煮,位于F島的核電站姐霍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏典唇。R本人自食惡果不足惜镊折,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚓聘。 院中可真熱鬧腌乡,春花似錦、人聲如沸夜牡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至急迂,卻和暖如春影所,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背僚碎。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工猴娩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人勺阐。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓卷中,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親渊抽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蟆豫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容