關(guān)于類(lèi)的重寫(xiě)多態(tài)

我們知道蜒灰,面向?qū)ο笕筇匦岳锵阴澹庋b、繼承和多態(tài)里强窖,多態(tài)是最復(fù)雜的凸椿。
多態(tài)的實(shí)現(xiàn)方式分為接口、重寫(xiě)Override和重載Overload:
接口不用說(shuō)了翅溺。
重寫(xiě)Override是在父子類(lèi)之間有相同的方法和參數(shù)脑漫,是父子類(lèi)的多態(tài)性。
重載Overload是一個(gè)類(lèi)內(nèi)部有同名方法但是參數(shù)不同咙崎,是一個(gè)類(lèi)的多態(tài)性优幸。(重載在編譯期就能確定使用了那個(gè)函數(shù),所以不是運(yùn)行時(shí)多態(tài)褪猛,有些學(xué)派因此認(rèn)為重載不算正宗的多態(tài))

這里面网杆,重寫(xiě)是一個(gè)難點(diǎn),特別它的多態(tài)性是在運(yùn)行時(shí)表現(xiàn)出來(lái)的,容易繞暈碳却,一般來(lái)講队秩,重寫(xiě)多態(tài)是這樣的:

A a=new B();

a叫做引用變量,引用變量指向的具體類(lèi)型和方法昼浦,在編譯時(shí)不能確定馍资,是在運(yùn)行時(shí)確定的。
重寫(xiě)在多態(tài)上的表現(xiàn)就是具體指向哪個(gè)重寫(xiě)方法:
首先关噪,超類(lèi)(A)中需要定義這個(gè)方法迷帜。
然后,引用對(duì)象(B)中定義了這個(gè)方法的最終形態(tài)色洞;

多態(tài)重寫(xiě)有三個(gè)必要條件:
1.繼承
2.重寫(xiě)
3.父類(lèi)引用指向子類(lèi)對(duì)象

我們先看規(guī)律,再根據(jù)兩個(gè)經(jīng)典例題來(lái)掌握規(guī)律的用法冠胯。

幾個(gè)規(guī)律

左右
變量多態(tài)看左邊火诸,
靜態(tài)多態(tài)看左邊,
方法多態(tài)看右邊(左邊的方法表里需要有這個(gè)方法)荠察。
優(yōu)先級(jí)
假設(shè)有個(gè)show(Object obj)函數(shù)置蜀,那么對(duì)于show函數(shù)所在的類(lèi)及其父類(lèi),已經(jīng)參數(shù)Object來(lái)說(shuō)悉盆,有固定的優(yōu)先級(jí)(JVM虛擬機(jī)里的方法表查詢(xún)機(jī)制盯荤,決定了這個(gè)優(yōu)先級(jí)):
this.show(O)>>super.show(O)>>this.show(super(O))>>super.show(super(O)),這是虛擬機(jī)多態(tài)的機(jī)制里定義的優(yōu)先級(jí)焕盟,具體意思是說(shuō):

優(yōu)先使用當(dāng)前類(lèi)的定義this.show(O)
次優(yōu)先使用父類(lèi)的定義super.show(O)
第三位使用當(dāng)前類(lèi)定義的父類(lèi)參數(shù)函數(shù)this.show(super(O))
最后使用父類(lèi)定義的父類(lèi)參數(shù)函數(shù)super.show(super(O))

例題1

    public class A{
        void a(){
            System.out.print("Aa");
        }
        void b(){
            System.out.print("Ab");
        }
    }

    public class B extends A{
        void b(){
            System.out.print("Bb");
        }
        void d(){
            System.out.print("Bd");
        }
    }
    
    private void doTest(){
        A a=new B();
        a.a(); //Aa 只有A有實(shí)現(xiàn)秋秤,不需要多態(tài)
        a.b(); //Bb 在子類(lèi)B有實(shí)現(xiàn),多態(tài)
        a.d(); //A的方法表中沒(méi)有d脚翘,編譯錯(cuò)誤
        B b=(B)a; //可以強(qiáng)轉(zhuǎn)
        b.a(); //Aa B沒(méi)有實(shí)現(xiàn)灼卢,向父類(lèi)A中尋找,并找到
        b.b(); //Bb B類(lèi)的方法
        b.d(); //Bd B類(lèi)的方法
    }

例題2

class A{
    public String show(D obj){
           return ("AD");
    } 
    public String show(A obj){

           return ("AA");
    } 
}   

class B extends A{
    public String show(B obj){
           return ("BB");
    }
    public String show(A obj){
           return ("BA");
    } 
}  
class C extends B{} 
class D extends B{}

//調(diào)用
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C(); 
D d = new D(); 

//其實(shí)就是考察從父類(lèi)/參數(shù)多態(tài)的優(yōu)先級(jí):this.show(O)>>super.show(O)>>this.show(super(O))>>super.show(super(O))

System.out.println(a1.show(b));  // ① AA来农,因?yàn)閰?shù)B是A鞋真,優(yōu)先級(jí)為this.show(super(O))
//相當(dāng)于this.show(O)>>super.show(O)>>this.show(super(O)) 這里 >>super.show(super(O))

System.out.println(a1.show(c));  // ② AA,同上
System.out.println(a1.show(d));  // ③ AD沃于,因?yàn)锳定義了show(D obj)涩咖,優(yōu)先級(jí)為this.show(O)
//相當(dāng)于this.show(O)這里>>super.show(O)>>this.show(super(O)) >>super.show(super(O))

System.out.println(a2.show(b));  // ④ BA,因?yàn)锳沒(méi)定義show(B obj)繁莹,只能找到show(A obj)檩互,還是優(yōu)先級(jí)為this.show(super(O))
//相當(dāng)于this.show(O)>>super.show(O)>>this.show(super(O)) 這里>>super.show(super(O))

System.out.println(a2.show(c));  // ⑤ AA,同上
System.out.println(a2.show(d));  // ⑥ AD咨演,因?yàn)锳定義了show(D obj)盾似,優(yōu)先級(jí)為this.show(O)
//相當(dāng)于this.show(O)這里>>super.show(O)>>this.show(super(O)) >>super.show(super(O))

System.out.println(b.show(b));   // ⑦ BB,因?yàn)锽定義了show(B obj),優(yōu)先級(jí)為this.show(O)
//相當(dāng)于this.show(O)這里>>super.show(O)>>this.show(super(O)) >>super.show(super(O))

System.out.println(b.show(c));   // ⑧ BB零院,因?yàn)锽定義了show(B obj)溉跃,優(yōu)先級(jí)為this.show(super(O))
//相當(dāng)于this.show(O)>>super.show(O)>>this.show(super(O)) 這里>>super.show(super(O))

System.out.println(b.show(d));   // ⑨ AD,因?yàn)锳定義了show(D obj)告抄,優(yōu)先級(jí)為super.show(O)
//相當(dāng)于this.show(O)>>super.show(O)這里>>this.show(super(O)) >>super.show(super(O))

總結(jié)

對(duì)于A(yíng) a=new B();這種形式的多態(tài)撰茎,B是A的子類(lèi),那么調(diào)用a.func(D obj)時(shí)打洼,需要注意這樣幾個(gè)問(wèn)題:
1.func函數(shù)在A(yíng)未定義龄糊、在B定義。會(huì)編譯錯(cuò)誤募疮,因?yàn)閍的函數(shù)僅限于A(yíng)定義過(guò)的炫惩,B的函數(shù)在a中不能訪(fǎng)問(wèn)
2.func函數(shù)在A(yíng)、B都有定義阿浓。這時(shí)應(yīng)采用B的實(shí)現(xiàn)他嚷。
3.func函數(shù)在A(yíng)定義,在B未定義芭毙。這時(shí)會(huì)采用A的實(shí)現(xiàn)筋蓖。
4.func函數(shù)在A(yíng)、B均未定義退敦。會(huì)編譯錯(cuò)誤粘咖。
5.func函數(shù)在A(yíng)、B都有定義侈百,但是func的參數(shù)沒(méi)有D瓮下,只有D的父類(lèi)C,那么需要按照this.show(super(O)) >>super.show(super(O))的順序去選擇函數(shù)钝域。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唱捣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子网梢,更是在濱河造成了極大的恐慌震缭,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件战虏,死亡現(xiàn)場(chǎng)離奇詭異拣宰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)烦感,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)巡社,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人手趣,你說(shuō)我怎么就攤上這事晌该》世螅” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵朝群,是天一觀(guān)的道長(zhǎng)燕耿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)姜胖,這世上最難降的妖魔是什么誉帅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮右莱,結(jié)果婚禮上蚜锨,老公的妹妹穿的比我還像新娘。我一直安慰自己慢蜓,他們只是感情好亚再,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著晨抡,像睡著了一般氛悬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凄诞,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音忍级,去河邊找鬼帆谍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛轴咱,可吹牛的內(nèi)容都是我干的汛蝙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼朴肺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窖剑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起戈稿,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤西土,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鞍盗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體需了,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年般甲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肋乍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敷存,死狀恐怖墓造,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤觅闽,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布帝雇,位于F島的核電站,受9級(jí)特大地震影響谱煤,放射性物質(zhì)發(fā)生泄漏摊求。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一刘离、第九天 我趴在偏房一處隱蔽的房頂上張望室叉。 院中可真熱鬧,春花似錦硫惕、人聲如沸茧痕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)踪旷。三九已至,卻和暖如春豁辉,著一層夾襖步出監(jiān)牢的瞬間令野,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工徽级, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留气破,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓餐抢,卻偏偏與公主長(zhǎng)得像现使,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旷痕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,783評(píng)論 1 10
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語(yǔ)閱讀 3,829評(píng)論 0 6
  • 進(jìn)入預(yù)產(chǎn)期月碳锈,需要每周產(chǎn)檢一次了。 今天孕36+欺抗,按醫(yī)生安排做了B超和胎心監(jiān)護(hù)及常規(guī)檢查售碳。 晚上回到家吃過(guò)飯也沒(méi)有...
    喵喵司令閱讀 277評(píng)論 0 0
  • 今天一整天,心情特別平靜绞呈,當(dāng)我意識(shí)到金錢(qián)在我生命中不是最重要的時(shí)候团滥,生命,健康报强,家庭顯得那么尊貴灸姊,感覺(jué)自己又是那么...
    斯拓之海閱讀 207評(píng)論 0 0
  • 每次海上航行都會(huì)帶本書(shū),作為領(lǐng)隊(duì)總是住在內(nèi)艙秉溉,晨昏只在手表上顯示力惯,所以在船上的時(shí)間大都是昏天黑地的睡覺(jué)碗誉,從來(lái)沒(méi)認(rèn)真...
    晨純_0944閱讀 519評(píng)論 0 2