(一)相關類
(二)問題以下輸出結果是什麼?
(三)答案
① 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
(四)分析
①②③比較好理解一般不會出錯④⑤就有點糊塗了為什麼輸出的不是B and B呢?!!先來回顧一下多態性
運行時多態性是面向對象程序設計代碼重用的一個最強大機制動態性的概念也可以被說成一個接口多個方法Java實現運行時多態性的基礎是動態方法調度它是一種在運行時而不是在編譯期調用重載方法的機制
方法的重寫Overriding和重載Overloading是Java多態性的不同表現重寫Overriding是父類與子類之間多態性的一種表現重載Overloading是一個類中多態性的一種表現如果在子類中定義某方法與其父類有相同的名稱和參數我們說該方法被重寫(Overriding)子類的對象使用這個方法時將調用子類中的定義對它而言父類中的定義如同被屏蔽了如果在一個類中定義了多個同名的方法它們或有不同的參數個數或有不同的參數類型則稱為方法的重載(Overloading)Overloaded的方法是可以改變返回值的類型方法的重寫Overriding和重載Overloading是Java多態性的不同表現重寫Overriding是父類與子類之間多態性的一種表現重載Overloading是一個類中多態性的一種表現如果在子類中定義某方法與其父類有相同的名稱和參數我們說該方法被重寫 (Overriding)子類的對象使用這個方法時將調用子類中的定義對它而言父類中的定義如同被屏蔽了如果在一個類中定義了多個同名的方法它們或有不同的參數個數或有不同的參數類型則稱為方法的重載(Overloading)Overloaded的方法是可以改變返回值的類型
當超類對象引用變量引用子類對象時被引用對象的類型而不是引用變量的類型決定了調用誰的成員方法但是這個被調用的方法必須是在超類中定義過的也就是說被子類覆蓋的方法 (但是如果強制把超類轉換成子類的話就可以調用子類中新添加而超類沒有的方法了)
好了先溫習到這裡言歸正傳!實際上這裡涉及方法調用的優先問題 優先級由高到低依次為thisshow(O)supershow(O)thisshow((super)O)supershow((super)O)讓我們來看看它是怎麼工作的
比如④
a
show(b)
a
是一個引用變量
類型為A
則this為a
b是B的一個實例
於是它到類A裡面找show(B obj)方法
沒有找到
於是到A的super(超類)找
而A沒有超類
因此轉到第三優先級this
show((super)O)
this仍然是a
這裡O為B
(super)O即(super)B即A
因此它到類A裡面找show(A obj)的方法
類A有這個方法
但是由於a
引用的是類B的一個對象
B覆蓋了A的show(A obj)方法
因此最終鎖定到類B的show(A obj)
輸出為
B and A
再比如⑧
b
show(c)
b是一個引用變量
類型為B
則this為b
c是C的一個實例
於是它到類B找show(C obj)方法
沒有找到
轉而到B的超類A裡面找
A裡面也沒有
因此也轉到第三優先級this
show((super)O)
this為b
O為C
(super)O即(super)C即B
因此它到B裡面找show(B obj)方法
找到了
由於b引用的是類B的一個對象
因此直接鎖定到類B的show(B obj)
輸出為
B and B
按照上面的方法
可以正確得到其他的結果
問題還要繼續
現在我們再來看上面的分析過程是怎麼體現出藍色字體那句話的內涵的
它說
當超類對象引用變量引用子類對象時
被引用對象的類型而不是引用變量的類型決定了調用誰的成員方法
但是這個被調用的方法必須是在超類中定義過的
也就是說被子類覆蓋的方法
還是拿a
show(b)來說吧
a
是一個引用變量
類型為A
它引用的是B的一個對象
因此這句話的意思是由B來決定調用的是哪個方法
因此應該調用B的show(B obj)從而輸出
B and B
才對
但是為什麼跟前面的分析得到的結果不相符呢?!問題在於我們不要忽略了藍色字體的後半部分
那裡特別指明
這個被調用的方法必須是在超類中定義過的
也就是被子類覆蓋的方法
B裡面的show(B obj)在超類A中有定義嗎?沒有!那就更談不上被覆蓋了
實際上這句話隱藏了一條信息
它仍然是按照方法調用的優先級來確定的
它在類A中找到了show(A obj)
如果子類B沒有覆蓋show(A obj)方法
那麼它就調用A的show(A obj)(由於B繼承A
雖然沒有覆蓋這個方法
但從超類A那裡繼承了這個方法
從某種意義上說
還是由B確定調用的方法
只是方法是在A中實現而已)
現在子類B覆蓋了show(A obj)
因此它最終鎖定到B的show(A obj)
這就是那句話的意義所在
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27004.html