日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
深入理解Java多態(tài)性

看過(guò)一些關(guān)于Java多態(tài)性的文章,參考了很多人的理解,加入了一些自己的看法,整理出來(lái)供大家參考,不一定完全正確,歡迎大家批評(píng)指正。

(一)相關(guān)類(lèi)

 
 
 
  1. class A ...{  
  2.          public String show(D obj)...{  
  3.                 return ("A and D");  
  4.          }   
  5.          public String show(A obj)...{  
  6.                 return ("A and A");  
  7.          }   
  8. }   
  9. class B extends A...{  
  10.          public String show(B obj)...{  
  11.                 return ("B and B");  
  12.          }  
  13.          public String show(A obj)...{  
  14.                 return ("B and A");  
  15.          }   
  16. }  
  17. class C extends B...{}   
  18. class D extends B...{}  

(二)問(wèn)題:以下輸出結(jié)果是什么?

 
 
 
  1. A a1 = new A();  
  2.         A a2 = new B();  
  3.         B b = new B();  
  4.         C c = new C();   
  5.         D d = new D();   
  6.         System.out.println(a1.show(b));   ①  
  7.         System.out.println(a1.show(c));   ②  
  8.         System.out.println(a1.show(d));   ③  
  9.         System.out.println(a2.show(b));   ④  
  10.         System.out.println(a2.show(c));   ⑤  
  11.         System.out.println(a2.show(d));   ⑥  
  12.         System.out.println(b.show(b));    ⑦  
  13.         System.out.println(b.show(c));    ⑧  
  14.         System.out.println(b.show(d));    ⑨     

(三)答案

①   A and A

②   A and A

③   A and D

④   B and A

⑤   B and A

⑥   A and D

⑦   B and B

⑧   B and B

⑨   A and D

(四)分析

①②③比較好理解,一般不會(huì)出錯(cuò)。④⑤就有點(diǎn)糊涂了,為什么輸出的不是"B and B”呢???!先來(lái)回顧一下多態(tài)性。

運(yùn)行時(shí)多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)代碼重用的一個(gè)最強(qiáng)大機(jī)制,Java多態(tài)性的概念也可以被說(shuō)成“一個(gè)接口,多個(gè)方法”。Java實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性的基礎(chǔ)是動(dòng)態(tài)方法調(diào)度,它是一種在運(yùn)行時(shí)而不是在編譯期調(diào)用重載方法的機(jī)制。

方法的重寫(xiě)Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫(xiě)Overriding是父類(lèi)與子類(lèi)之間多態(tài)性的一種表現(xiàn),重載Overloading是一個(gè)類(lèi)中多態(tài)性的一種表現(xiàn)。如果在子類(lèi)中定義某方法與其父類(lèi)有相同的名稱(chēng)和參數(shù),我們說(shuō)該方法被重寫(xiě)(Overriding)。子類(lèi)的對(duì)象使用這個(gè)方法時(shí),將調(diào)用子類(lèi)中的定義,對(duì)它而言,父類(lèi)中的定義如同被“屏蔽”了。如果在一個(gè)類(lèi)中定義了多個(gè)同名的方法,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類(lèi)型,則稱(chēng)為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類(lèi)型。方法的重寫(xiě)Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫(xiě)Overriding是父類(lèi)與子類(lèi)之間多態(tài)性的一種表現(xiàn),重載Overloading是一個(gè)類(lèi)中Java多態(tài)性的一種表現(xiàn)。如果在子類(lèi)中定義某方法與其父類(lèi)有相同的名稱(chēng)和參數(shù),我們說(shuō)該方法被重寫(xiě) (Overriding)。子類(lèi)的對(duì)象使用這個(gè)方法時(shí),將調(diào)用子類(lèi)中的定義,對(duì)它而言,父類(lèi)中的定義如同被“屏蔽”了。如果在一個(gè)類(lèi)中定義了多個(gè)同名的方法,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類(lèi)型,則稱(chēng)為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類(lèi)型。

當(dāng)超類(lèi)對(duì)象引用變量引用子類(lèi)對(duì)象時(shí),被引用對(duì)象的類(lèi)型而不是引用變量的類(lèi)型決定了調(diào)用誰(shuí)的成員方法,但是這個(gè)被調(diào)用的方法必須是在超類(lèi)中定義過(guò)的,也就是說(shuō)被子類(lèi)覆蓋的方法。 (但是如果強(qiáng)制把超類(lèi)轉(zhuǎn)換成子類(lèi)的話(huà),就可以調(diào)用子類(lèi)中新添加而超類(lèi)沒(méi)有的方法了。)

好了,先溫習(xí)到這里,言歸正傳!實(shí)際上這里涉及方法調(diào)用的優(yōu)先問(wèn)題 ,優(yōu)先級(jí)由高到低依次為:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。讓我們來(lái)看看它是怎么工作的。

比如④,a2.show(b),a2是一個(gè)引用變量,類(lèi)型為A,則this為a2,b是B的一個(gè)實(shí)例,于是它到類(lèi)A里面找show(B obj)方法,沒(méi)有找到,于是到A的super(超類(lèi))找,而A沒(méi)有超類(lèi),因此轉(zhuǎn)到第三優(yōu)先級(jí)this.show((super)O),this仍然是a2,這里O為B,(super)O即(super)B即A,因此它到類(lèi)A里面找show(A obj)的方法,類(lèi)A有這個(gè)方法,但是由于a2引用的是類(lèi)B的一個(gè)對(duì)象,B覆蓋了A的show(A obj)方法,因此最終鎖定到類(lèi)B的show(A obj),輸出為"B and A”。

再比如⑧,b.show(c),b是一個(gè)引用變量,類(lèi)型為B,則this為b,c是C的一個(gè)實(shí)例,于是它到類(lèi)B找show(C obj)方法,沒(méi)有找到,轉(zhuǎn)而到B的超類(lèi)A里面找,A里面也沒(méi)有,因此也轉(zhuǎn)到第三優(yōu)先級(jí)this.show((super)O),this為b,O為C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是類(lèi)B的一個(gè)對(duì)象,因此直接鎖定到類(lèi)B的show(B obj),輸出為"B and B”。

按照上面的方法,可以正確得到其他的結(jié)果。

問(wèn)題還要繼續(xù),現(xiàn)在我們?cè)賮?lái)看上面的分析過(guò)程是怎么體現(xiàn)出藍(lán)色字體那句話(huà)的內(nèi)涵的。它說(shuō):當(dāng)超類(lèi)對(duì)象引用變量引用子類(lèi)對(duì)象時(shí),被引用對(duì)象的類(lèi)型而不是引用變量的類(lèi)型決定了調(diào)用誰(shuí)的成員方法,但是這個(gè)被調(diào)用的方法必須是在超類(lèi)中定義過(guò)的,也就是說(shuō)被子類(lèi)覆蓋的方法。還是拿a2.show(b)來(lái)說(shuō)吧。

a2是一個(gè)引用變量,類(lèi)型為A,它引用的是B的一個(gè)對(duì)象,因此這句話(huà)的意思是由B來(lái)決定調(diào)用的是哪個(gè)方法。因此應(yīng)該調(diào)用B的show(B obj)從而輸出"B and B”才對(duì)。但是為什么跟前面的分析得到的結(jié)果不相符呢?!問(wèn)題在于我們不要忽略了藍(lán)色字體的后半部分,那里特別指明:這個(gè)被調(diào)用的方法必須是在超類(lèi)中定義過(guò)的,也就是被子類(lèi)覆蓋的方法。B里面的show(B obj)在超類(lèi)A中有定義嗎?沒(méi)有!那就更談不上被覆蓋了。實(shí)際上這句話(huà)隱藏了一條信息:它仍然是按照方法調(diào)用的優(yōu)先級(jí)來(lái)確定的。它在類(lèi)A中找到了show(A obj),如果子類(lèi)B沒(méi)有覆蓋show(A obj)方法,那么它就調(diào)用A的show(A obj)(由于B繼承A,雖然沒(méi)有覆蓋這個(gè)方法,但從超類(lèi)A那里繼承了這個(gè)方法,從某種意義上說(shuō),還是由B確定調(diào)用的方法,只是方法是在A(yíng)中實(shí)現(xiàn)而已);現(xiàn)在子類(lèi)B覆蓋了show(A obj),因此它最終鎖定到B的show(A obj)。這就是那句話(huà)的意義所在,到這里,我們可以清晰的理解Java的多態(tài)性了。

【編輯推薦】

  1. 總結(jié)Java Web中幾個(gè)函數(shù)的作用
  2. 在Java應(yīng)用程序中使用Jfreechart配置
  3. Java虛擬機(jī)內(nèi)部構(gòu)成淺析
  4. 淺談Java線(xiàn)程的生命周期
  5. 關(guān)于Java繼承的一些復(fù)習(xí)

本文題目:深入理解Java多態(tài)性
文章位置:http://www.dlmjj.cn/article/djeddop.html