C#接口和抽象类经典示例

.NET Framework是学习的最好资源,有意识的研究FCL是每个.NET程序员的必修课,关于接口和抽象类在FCL中的使用,我有以下的建议:

FCL对集合类使用了基于接口的设计,所以请关注System.Collections中关于接口的设计实现;

FCL对数据流相关类使用了基于抽象类的设计,所以请关注System.IO.Stream类的抽象类设计机制。

C#接口和抽象类Animal示例

下面的实例,本示例没有阐述抽象类和接口在设计模式中的应用,因为那将是另一篇有讨论价值的文本,本文着眼与概念和原则的把握,但是真正的应用来自于具体的需求规范。

设计结构如图所示:

设计结构图

1. 定义抽象类

  1. public abstract class Animal   
  2. {   
  3. protected string _name;   
  4. //声明抽象属性   
  5. public abstract string Name   
  6. {   
  7. get;   
  8. }   
  9.  
  10. //声明抽象方法   
  11.  
  12. public abstract void Show();   
  13.  
  14. //实现一般方法   
  15.  
  16. public void MakeVoice()   
  17. {   
  18. Console.WriteLine("All animals can make voice!");   
  19. }   
  20. }   
  21.  
  22.    

2. 定义接口

  1. public interface IAction   
  2. {   
  3. //定义公共方法标签   
  4. void Move();   
  5. }  

3. 实现抽象类和接口

  1. public class Duck : Animal, IAction   
  2. {   
  3. public Duck(string name)   
  4. {   
  5. _name = name;   
  6. }   
  7. //重载抽象方法   
  8.  
  9. public override void Show()   
  10. {   
  11. Console.WriteLine(_name + " is showing for you.");   
  12. }   
  13.  
  14. //重载抽象属性   
  15.  
  16. public override string Name   
  17. {   
  18. get { return _name;}   
  19. }   
  20.  
  21. //实现接口方法   
  22.  
  23. public void Move()   
  24. {   
  25. Console.WriteLine("Duck also can swim.");   
  26. }   
  27. }   
  28.  
  29. public class Dog : Animal, IAction   
  30. {   
  31. public Dog(string name)   
  32. {   
  33. _name = name;   
  34. }   
  35. public override void Show()   
  36. {   
  37. Console.WriteLine(_name + " is showing for you.");   
  38. }   
  39.  
  40. public override string Name   
  41. {   
  42. get { return _name; }   
  43.  
  44. }   
  45.  
  46. public void Move()   
  47. {   
  48. Console.WriteLine(_name + " also can run.");   
  49. }   
  50. }   
  51.  

4. 客户端实现

  1. public class TestAnmial   
  2. {   
  3. public static void Main(string [] args)   
  4. {   
  5. Animal duck = new Duck("Duck");   
  6. duck.MakeVoice();   
  7. duck.Show();   
  8. Animal dog = new Dog("Dog");   
  9. dog.MakeVoice();   
  10. dog.Show();   
  11. IAction dogAction = new Dog("A big dog");   
  12. dogAction.Move();   
  13. }   
  14. }   

dunai认为:抽象类是提取具体类的公因式,而接口是为了将一些不相关的类“杂凑”成一个共同的群体。至于他们在各个语言中的句法,语言细节并不是我关心的重点。

Artech认为:所代码共用和可扩展性考虑,尽量使用Abstract Class。当然接口在其他方面的优势,我认为也不可忽视。

shenfx认为:当在差异较大的对象间寻求功能上的共性时,使用接口;当在共性较多的对象间寻求功能上的差异时,使用抽象基类。

最后,有关C#接口和抽象类的学习,MSDN的建议:

如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。

如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。

如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。

如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。

posted on 2010-12-15 16:31  飞翔-方向 积累 沉淀  阅读(934)  评论(0编辑  收藏  举报