組合介面時名字衝突問題
之前從沒注意到實現多個介面可能會存在方法衝突的問題,在《Thinking in Java》中看到一個有趣的例子,其本質是重載和重寫的問題,關於重載和重寫的概念和區別可參看另一篇文章Java基礎一:面向對象的特徵。首先看例子:
1 interface I1 {
2 void f;
3 }
4
5 interface I2 {
6 int f(int i);
7 }
8
9 interface I3 {
10 int f;
11 }
12
13 class C {
14 public int f{
15 return 1;
16 }
17 }
18
19 class C2 implements I1,I2{//重載
20 @Override
21 public void f {}
22
23 @Override
24 public int f(int i) {
25 return 0;
26 }
27 }
28
29 class C3 extends C implements I2{
30 @Override
31 public int f(int i) {//重載
32 return 0;
33 }
34 }
35
36 class C4 extends C implements I3{
37 @Override
38 public int f { //重寫
39 return 0;
40 }
41 }
42
43 // class C5 extends C implements I1{}
44 //
45 // interface I4 extends I1,I3{}
46
47 public static void main(String[] args){
48 MethodCollision methodCollision = new MethodCollision;
49 C4 c4 = methodCollision.new C4;
50 System.out.println(c4.f);//輸出0
51 }
其中介面I1中存在方法void f,I2中存在int f(int i),I3中存在int f,類C中存在int f的方法。
C2類實現介面I1和I2,其中實現的方法void f和int f(int i)具有不同的簽名,屬於重載;
C3類實現介面I2、繼承C,C3實現I2中的int f(int i),並繼承C中的int f方法,它們具有不同的簽名,屬於重載;
C4類實現介面I3、繼承C,C4實現I3中的int f,並繼承C中的int f方法,它們具有相同的簽名,並且返回值類型也相同,屬於重寫(從程序輸出0可以說明);
C5類實現介面I1、繼承C,理論上,C5類會分別實現和繼承I1方法void f和C方法int f,它們具有相同的簽名,不同的返回值類型,既不是重寫,也不能重載,故編譯器提示錯誤;
I4介面繼承I1和I3,同樣理論上繼承void f和int f,但既不是重寫,也無法重載,編譯器報錯。
另一個有趣問題是,我如果將介面I1中的void f改為int f,會產生什麼效果呢?
1 interface I1 {
2 int f;
3 }
4
5 interface I2 {
6 int f(int i);
7 }
8
9 interface I3 {
10 int f;
11 }
12
13 class C {
14 public int f{
15 return 1;
16 }
17 }
18
19 class C2 implements I1,I2{//重載
20 @Override
21 public int f {
22 return 0;
23 }
24
25 @Override
26 public int f(int i) {
27 return 0;
28 }
29 }
30
31 class C3 extends C implements I2{
32 @Override
33 public int f(int i) {//重載
34 return 0;
35 }
36 }
37
38 class C4 extends C implements I3{
39 @Override
40 public int f { //重寫
41 return 0;
42 }
43 }
44
45 class C5 extends C implements I1{}//不重寫該函數,繼承自C的方法即為實現
46
47 interface I4 extends I1,I3{}
48
49 class C6 implements I4{//I1和I3的方法一樣,實現類只實現一個
50 @Override
51 public int f {
52 return 0;
53 }
54 }
55
56 public static void main(String[] args){
57 MethodCollision methodCollision = new MethodCollision;
58 C4 c4 = methodCollision.new C4;
59 System.out.println(c4.f);//0
60
61 C5 c5 = methodCollision.new C5;
62 System.out.println(c5.f);//1
63 }
其中介面I1中存在方法int f,I2中存在int f(int i),I3中存在int f,類C中存在int f的方法。
C2類實現介面I1和I2,其中實現的方法int f和int f(int i)具有不同的簽名,屬於重載;
C3類實現介面I2、繼承C,屬於重載;
C4類實現介面I3、繼承C,屬於重寫(從程序輸出0可以說明);
C5類實現介面I1、繼承C,C5類會分別實現和繼承I1方法int f和C方法int f,其與C4類是相同的,它是重寫嗎?不是,因為其繼承自C的函數已經實現了該介面,沒有重寫(從程序輸出1可以說明);
I4介面繼承I1和I3,同時繼承I1和I3的int f,它們具有相同的方法簽名和返回值類型,所以I4具有一個int f(可通過C6實現類看出);
C6類實現介面I4,具有一個實現函數int f。
總結:
- 類不可以多重繼承,介面可以多重繼承;
- 組合介面時,可能會存在方法重載和重寫的問題,並且可能會引入代碼的混亂,降低代碼可讀性,故盡量避免這種情況;
- 通過該例,可以學習繼承、介面實現、重載和重寫概念,其中一點是類繼承的方法也可以作為實現介面的實現方法。
※我的前端進階之路
※vue2入坑隨記(一)
※Visual Studio Package 插件開發之自動生成實體工具
TAG:達人科技 |
※電腦程序衝突或者系統故障會出現藍屏,分析藍屏問題
※你真的會問問題嗎?是不是有時候一個問題就引發了尷尬或者衝突?
※張俊列:《衝突與和合——課程改革的人性邏輯》序言
※名記爆張呈棟馬寧衝突細節 有攻有防句句扎心比球賽精彩
※與合伙人發生衝突時,這5個辦法有助於你更好地解決問題
※電腦網路連接中出現ip衝突應該這樣解決問題
※電腦IP經常出現地址衝突問題,應該嘗試這樣解決
※土耳其總統:聯合國無視加沙衝突 其未能解決世界問題
※歐佩克峰會或成內部衝突攤牌時刻 卡達問題將成焦點!
※西班牙疑似越位球引發衝突時 誰注意到摩洛哥主帥的舉動 裁判點贊
※威少避談兩隊衝突:下一個問題
※閻學通:美或放棄朝核問題 轉而在其他問題上製造衝突!
※聯合國人權理事會欲派小組調查加沙衝突相關問題,美澳投反對票
※大國軍事衝突已成新的時代問題?美俄都在做準備!
※難題來了!曝范志毅正面回應衝突事件,一語說出多少人心聲
※在拍攝《人民的名義》時 這幾個大腕級的人物因檔期衝突而遺憾
※事情反轉?衝突事件是韓國選手故意踢人加語言攻擊所致,有錄音!
※寶寶起名當五行八字衝突時如何解決?專家支招
※如何及時有效的處理職場中的衝突問題
※沙特公布初步調查結果:失蹤記者已死,系衝突所致