【Java】探究Java实现多接口时同名方法冲突问题
問題由來
今天與朋友們聊天談到C++的多繼承問題,朋友覺得非常麻煩,特別是遇到方法重復的時候。
這時,我突然想到既然Java通過多接口的implement代替了復雜的多繼承,那如果兩個甚至多個接口存在相同的方法,會被怎樣處理呢?
有這樣幾種想法:
- A:會爆出CE(編譯錯誤)。
- B:調用時會爆出RE(運行時異常)。
- C:會按照編譯時類型來指定,否則會報錯。
- D:實現的是先被指定的接口的方法。
- E:兩個接口的方法被“合并”了。
由于大家對Java的研究還是不夠深,還是沒有一個定論。
為探究設計的Demo
先來看這樣一個例子:
首先是有兩個接口A和B,各有各的方法(含一個同名的say()方法):
然后,我們設計一個C類來實現A和B兩個接口:
public class C implements A, B {@Overridepublic void say() {System.out.println("說話");}@Overridepublic void walk() {System.out.println("行走");}@Overridepublic void sleep() {System.out.println("睡覺");} }設計測試與結果分析
public static void main(String[] args) {C c = new C();c.say();}運行是正常的,可見不是簡單的CE或者RE,排除A、B、C三種想法。
然后我們加上新的語句:
發現均能達到效果。
由于我采用的是記事本編輯+命令行終端運行的方式,所以不便于直接確定say()方法是從哪里繼承過來的,這時可以打開Eclipse IDE,找到say(),按住Ctrl,點擊Super Implement,可以看到:
- c的say()來自A。
- a的say()來自A。
- b的say()來自B。
但這還不夠,我們不能確定D想法是不是靠譜,我們需要做一組對照實驗,對照組就是上述的例子,實驗組就是在其他都相同的情況下把implement后面的A和B換序。
public class C implements B, A {@Overridepublic void say() {System.out.println("說話");}@Overridepublic void walk() {System.out.println("行走");}@Overridepublic void sleep() {System.out.println("睡覺");} }這時,我們發現c的say()指向的是B。
這印證了我們的D思路。
因為Eclipse IDE自身有一些問題,所以我們不能直接相信Eclipse,D與E之間還需要繼續探究。
利用javap命令繼續分析
5.得出結論
由于是接口方法,畢竟不是真正的多繼承,還是存在一定的差別的。
下面的內容,先聲明——由于我個人對這里的認識也不是很深,所以只講出自己的看法:
(1)如果是
A a = new C();或是
B b = new C();這樣兩種情況,則依據javap可以看出,重名方法會跟著接口走,畢竟是編譯時類型嘛。
(2)如果是
C c = new C();這種情況,編譯時類型和運行時類型相同,都是實現類的話,我認為是會優先“繼承”先implement的接口的同名方法,然后實現。此時,這個方法是子類的,它的super是優先implement的接口的public abstract方法。
因此,個人認為,D想法和E想法都有一定的成立理由,原因應該是二者的結合。
感想
- “書到用時方恨少”,有這樣的困惑,還是自己所學不精的代價,以后應該繼續深入的學習,有刨根問底的精神去探究問題。
- 探究精神很可貴,雖不知標準答案,但我們在遇到無法解決的問題時,可以自主的探究求解,得到“實驗結論”。
如有錯誤,歡迎批評指正,謝謝!
總結
以上是生活随笔為你收集整理的【Java】探究Java实现多接口时同名方法冲突问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python】Matplotlib在直
- 下一篇: 【Java】I/O流体系中流的分类