编译时多态和运行时多态
在JAVA中有兩種多態(tài)是指:運(yùn)行時(shí)多態(tài)和編譯時(shí)多態(tài)。
關(guān)于類的多態(tài)性簡介如下:
多態(tài)(polymorphism)意為一個(gè)名字可具有多種語義.在程序設(shè)計(jì)語言中,多態(tài)性是指”一種定義,多種實(shí)現(xiàn)”.例如,運(yùn)算符+有多種含義,究竟執(zhí)行哪種運(yùn)算取決于參加運(yùn)算的操作數(shù)類型:
1+2 //加法運(yùn)算符
“1” + “2” //字符串連接運(yùn)算,操作數(shù)是字符串
多態(tài)性是面向?qū)ο蟮暮诵奶卣髦?/span>,類的多態(tài)性提供類中成員設(shè)計(jì)的靈活性和方法執(zhí)行的多樣性.
1、類多態(tài)性表現(xiàn)
(1)方法重載
重載表現(xiàn)為同一個(gè)類中方法的多態(tài)性.一個(gè)類生命多個(gè)重載方法就是為一種功能提供多種實(shí)現(xiàn).編譯時(shí),根據(jù)方法實(shí)際參數(shù)的數(shù)據(jù)類型\個(gè)數(shù)和次序,決定究竟應(yīng)該執(zhí)行重載方法中的哪一個(gè).
(2)子類重定義從父類繼承來的成員
當(dāng)子類從父類繼承來的成員不適合子類時(shí) ,子類不能刪除它們,但可以重定義它們,使父類成員適應(yīng)子類的新需求.子類重定義父類成員,同名成員在父類與子類之間表現(xiàn)出多態(tài)性,父類對(duì)象引用父類成員,子類對(duì)象引用子類成員,不會(huì)產(chǎn)生沖突和混亂.
子類可重定義父類的同名成員變量,稱子類隱藏父類成員變量.子類也可以重定義父類的同名成員方法,當(dāng)子類方法的參數(shù)列表與父類方法參數(shù)列表完全相同時(shí),稱為子類方法覆蓋(override)父類方法。覆蓋父類方法時(shí),子類方法的訪問權(quán)限不能小于父類方法的權(quán)限。
由于Object類的equals()方法比較兩個(gè)對(duì)象的引用是否相等而不是值是否相等,因此一個(gè)類要覆蓋Object類的equals()方法,提供本類兩個(gè)對(duì)象比較相等方法.
覆蓋表現(xiàn)為父類與子類之間方法的多態(tài)性.java 尋找執(zhí)行方法的原則是:從對(duì)象所屬的類開始,尋找匹配的方法執(zhí)行,如果當(dāng)前類中沒有匹配的方法,則逐層向上依次在父類或祖先類中尋找匹配方法,直到Object類.
2、super 引用
在子類的成員方法中,可以使用代詞super引用父類成員.super引用的語法如下:
super([參數(shù)列表]) //在子類的構(gòu)造方法體中,調(diào)用父類的構(gòu)造方法
super.成員變量 //當(dāng)子類隱藏父類成員變量時(shí),引用父類同名成員變量
super.成員方法([參數(shù)列表]) //當(dāng)子類覆蓋父類成員方法時(shí),調(diào)用父類同名成員方法
*注意:super引用沒有單獨(dú)使用的語法
3、多態(tài)性有兩種:
1)編譯時(shí)多態(tài)性
對(duì)于多個(gè)同名方法,如果在編譯時(shí)能夠確定執(zhí)行同名方法中的哪一個(gè),則稱為編譯時(shí)多態(tài)性.
2)運(yùn)行時(shí)多態(tài)性
如果在編譯時(shí)不能確定,只能在運(yùn)行時(shí)才能確定執(zhí)行多個(gè)同名方法中的哪一個(gè),則稱為運(yùn)行時(shí)多態(tài)性.
方法覆蓋表現(xiàn)出兩種多態(tài)性,當(dāng)對(duì)象獲得本類實(shí)例時(shí),為編譯時(shí)多態(tài)性,否則為運(yùn)行時(shí)多態(tài)性,例如:
XXXX x1 = new XXXX(參數(shù)列表); //對(duì)象獲得本類實(shí)例,對(duì)象與其引用的實(shí)例類型一致
XXX xx1 = new XXX(參數(shù)列表);
x1.toString(); //編譯時(shí)多態(tài)性,執(zhí)行XXX類的方法.
xx1.toString(); //編譯時(shí)多態(tài)性,執(zhí)行XXXX類覆蓋的方法.
XXXX為XXX的父類.
由于子類對(duì)象既是父類對(duì)象,父類對(duì)象與子類對(duì)象之間具有賦值相容性,父類對(duì)象能夠被賦值為子類對(duì)象.例如,
XXXX x2 = new XXX(參數(shù)列表); //父類對(duì)象獲得子類實(shí)例,子類對(duì)象即是父類對(duì)象
x2.toString(); //運(yùn)行時(shí)多態(tài)
x2聲明為父類對(duì)象卻獲得子類XXX的實(shí)例,那么x2.toString()究竟執(zhí)行父類方法還是執(zhí)行子類覆蓋的方法呢?
這分為兩種情況:
取決于子類是否覆蓋父類方法.如果子類覆蓋父類方法,則執(zhí)行子類方法;
如果沒有覆蓋,則執(zhí)行父類方法.
在編譯時(shí),僅僅依據(jù)對(duì)象所屬的類,系統(tǒng)無法確定到底應(yīng)該執(zhí)行那個(gè)類的方法,只有運(yùn)行時(shí)才能確定,因此這是運(yùn)行時(shí)多態(tài).
父類對(duì)象并不能執(zhí)行所有的子類方法,只能執(zhí)行那些父類中聲明\子類覆蓋的子類方法.
?
?
轉(zhuǎn)載于:https://blog.51cto.com/tyq510/1601058
總結(jié)
以上是生活随笔為你收集整理的编译时多态和运行时多态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js escape 与php escap
- 下一篇: com组件