顯示接口實現與隱式接口實現
何為顯式接口實現、隱式接口實現?簡單概括,使用接口名作為方法名的前綴,這稱為“顯式接口實現”;傳統的實現方式,稱為“隱式接口實現”。下面給個例子。
IChineseGreeting接口,如果需要具備中文的問好行為,需繼承此接口。
?
1 //IChineseGreeting.cs2 ?3 interface IChineseGreeting4 5 {6 7 void SayHello();8 9 } 10 11 12 13 ChinesePeople類實現IChineseGreeting接口。 14 15 16 17 ?//ChinesePeople.cs 18 ? 19 class ChinesePeople:IChineseGreeting 20 21 { 22 23 public void SayHello() 24 25 { 26 27 Console.WriteLine("你好!"); 28 29 } 30 31 32 33 }
這樣的實現就是“隱式接口實現”,用public關鍵字作方法的訪問修飾符,我們通常都是這么做的。
你可以這樣調用:
?
ChinesePeople chinese = new ChinesePeople();chinese.SayHello();
?
?
也可以這樣調用
?
IChineseGreeting otherChinese = new ChinesePeople();otherChinese.SayHello();
類和接口都能訪問到SayHello()方法。
如果“顯式接口實現”,就應該是這樣。
?
特別提醒:用于實現一個接口的所有方法都必須具有public可訪問性。但是,假如使用顯式接口實現,不應該為方法添加一個訪問修飾符。
?
這時你只能這樣調用:
?
?
IChineseGreeting otherChinese = new ChinesePeople();otherChinese.SayHello();
不能通過類來調用
?
ChinesePeople chinese = new ChinesePeople();chinese.SayHello(); //錯誤,不能訪問。
記住:顯示實現,只有接口可以訪問。
?
顯示接口實現看起來有點繁瑣,而且還不能通過類來訪問接口方法。為什么還要有“顯式實現接口”呢?
其實,多個接口可能包含具有相同名稱、相同返回類型和相同參數的方法。如果一個類實現了多個接口,而且接口中的方法具有相同的簽名,就可以通過顯式接口實現來消除它們之間的歧義。顯式接口實現標識出哪個方法屬于哪個接口。
?
IEnglishGreeting接口,如果需要具備英文的問好行為,需繼承此接口。
?
1 //IEnglishGreeting.cs 2 ? 3 interface IEnglishGreeting 4 5 { 6 7 void SayHello(); 8 9 }
可以發現,該接口中的SayHello方法簽名和IChineseGreeting接口中一樣。
?
1 class ChinesePeople:IChineseGreeting,IEnglishGreeting2 3 {4 5 void IChineseGreeting.SayHello()6 7 {8 9 Console.WriteLine("你好!"); 10 11 } 12 13 void IEnglishGreeting.SayHello() 14 15 { 16 17 Console.WriteLine("Hello!"); 18 19 } 20 21 22 23 }
?
?
可以這樣調用:
?
ChinesePeople chinese = new ChinesePeople();(chinese as IChineseGreeting).SayHello();(chinese as IEnglishGreeting).SayHello();
----------------------------------------------------------------------------------------
此外,如果顯示實現接口的類中還有該類特有的方法,此時會帶來一些不便。
例如,使ChinesePeople具有Play()方法。
?
?
這就帶來一個問題,要調用SayHello()方法時,必須通過接口實現,而此時Play()方法就無法訪問。因為現在將對象看作IChineseGreeting接口了,而接口中沒有Play()方法。
同樣,如果通過類實現,就無法訪問到SayHello()方法。
必須通過強制轉換來解決這個問題。
?
?
IChineseGreeting chinese = new ChinesePeople();chinese.SayHello();//chinese.Play(); 錯誤,無法訪問(chinese as ChinesePeople).Play();//強制轉換后,可以訪問
?
隱式接口實現不存在此問題。
?
總結:
- 當類實現一個接口時,通常使用隱式接口實現,這樣可以方便的訪問接口方法和類自身具有的方法和屬性。
- 當類實現多個接口時,并且接口中包含相同的方法簽名,此時使用顯式接口實現。即使沒有相同的方法簽名,仍推薦使用顯式接口,因為可以標識出哪個方法屬于哪個接口。
- 隱式接口實現,類和接口都可訪問接口中方法。顯式接口實現,只能通過接口訪問。