C#接口和抽象類的經(jīng)典示例與比對(duì)
C#接口和抽象類絕對(duì)經(jīng)典示例
.NET Framework是學(xué)習(xí)的最好資源,有意識(shí)的研究FCL是每個(gè).NET程序員的必修課,關(guān)于接口和抽象類在FCL中的使用,我有以下的建議:
FCL對(duì)集合類使用了基于接口的設(shè)計(jì),所以請(qǐng)關(guān)注System.Collections中關(guān)于接口的設(shè)計(jì)實(shí)現(xiàn);
FCL對(duì)數(shù)據(jù)流相關(guān)類使用了基于抽象類的設(shè)計(jì),所以請(qǐng)關(guān)注System.IO.Stream類的抽象類設(shè)計(jì)機(jī)制。
C#接口和抽象類Animal示例
下面的實(shí)例,因?yàn)槭俏业睦斫猓虼私o經(jīng)典打上“相對(duì)”的記號(hào),至于什么時(shí)候晉升為“絕對(duì)”,就看我在.NET追求的路上,是否能夠一如既往的如此執(zhí)著,因此我將把相對(duì)重構(gòu)到絕對(duì)為止(呵呵)。 本示例沒有闡述抽象類和接口在設(shè)計(jì)模式中的應(yīng)用,因?yàn)槟菍⑹橇硪黄杏懻搩r(jià)值的文本,本文著眼與概念和原則的把握,但是真正的應(yīng)用來自于具體的需求規(guī)范。
設(shè)計(jì)結(jié)構(gòu)如圖所示:
1. 定義抽象類
- public abstract class Animal
- {
- protected string _name;
- //聲明抽象屬性
- public abstract string Name
- {
- get;
- }
- //聲明抽象方法
- public abstract void Show();
- //實(shí)現(xiàn)一般方法
- public void MakeVoice()
- {
- Console.WriteLine("All animals can make voice!");
- }
- }
2. 定義接口
- public interface IAction
- {
- //定義公共方法標(biāo)簽
- void Move();
- }
3. 實(shí)現(xiàn)抽象類和接口
- public class Duck : Animal, IAction
- {
- public Duck(string name)
- {
- _name = name;
- }
- //重載抽象方法
- public override void Show()
- {
- Console.WriteLine(_name + " is showing for you.");
- }
- //重載抽象屬性
- public override string Name
- {
- get { return _name;}
- }
- //實(shí)現(xiàn)接口方法
- public void Move()
- {
- Console.WriteLine("Duck also can swim.");
- }
- }
- public class Dog : Animal, IAction
- {
- public Dog(string name)
- {
- _name = name;
- }
- public override void Show()
- {
- Console.WriteLine(_name + " is showing for you.");
- }
- public override string Name
- {
- get { return _name; }
- }
- public void Move()
- {
- Console.WriteLine(_name + " also can run.");
- }
- }
4. 客戶端實(shí)現(xiàn)
- public class TestAnmial
- {
- public static void Main(string [] args)
- {
- Animal duck = new Duck("Duck");
- duck.MakeVoice();
- duck.Show();
- Animal dog = new Dog("Dog");
- dog.MakeVoice();
- dog.Show();
- IAction dogAction = new Dog("A big dog");
- dogAction.Move();
- }
- }
dunai認(rèn)為:抽象類是提取具體類的公因式,而接口是為了將一些不相關(guān)的類“雜湊”成一個(gè)共同的群體。至于他們?cè)诟鱾€(gè)語言中的句法,語言細(xì)節(jié)并不是我關(guān)心的重點(diǎn)。
Artech認(rèn)為:所代碼共用和可擴(kuò)展性考慮,盡量使用Abstract Class。當(dāng)然接口在其他方面的優(yōu)勢(shì),我認(rèn)為也不可忽視。
shenfx認(rèn)為:當(dāng)在差異較大的對(duì)象間尋求功能上的共性時(shí),使用接口;當(dāng)在共性較多的對(duì)象間尋求功能上的差異時(shí),使用抽象基類。
最后,有關(guān)C#接口和抽象類的學(xué)習(xí),MSDN的建議:
如果預(yù)計(jì)要?jiǎng)?chuàng)建組件的多個(gè)版本,則創(chuàng)建抽象類。抽象類提供簡單易行的方法來控制組件版本。通過更新基類,所有繼承類都隨更改自動(dòng)更新。另一方面,接口一旦創(chuàng)建就不能更改。如果需要接口的新版本,必須創(chuàng)建一個(gè)全新的接口。
如果創(chuàng)建的功能將在大范圍的全異對(duì)象間使用,則使用接口。抽象類應(yīng)主要用于關(guān)系密切的對(duì)象,而接口最適合為不相關(guān)的類提供通用功能。
如果要設(shè)計(jì)小而簡練的功能塊,則使用接口。如果要設(shè)計(jì)大的功能單元,則使用抽象類。
如果要在組件的所有實(shí)現(xiàn)間提供通用的已實(shí)現(xiàn)功能,則使用抽象類。抽象類允許部分實(shí)現(xiàn)類,而接口不包含任何成員的實(shí)現(xiàn)。
【編輯推薦】