接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现,CLR 允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。但是注意:C# 中不能包含任何静态成员。一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方 法。
定义方法为:
- public interface System.IComparable
- {
- int CompareTo(object o);
- }
- public class TestCls: IComparable
- {
- public TestCls()
- {
- }
- private int _value;
- public int Value
- {
- get { return _value; }
- set { _value = value; }
- }
- public int CompareTo(object o)
- {
- //使用as模式进行转型判断
- TestCls aCls = o as TestCls;
- if (aCls != null)
- {
- //实现抽象方法
- return _value.CompareTo(aCls._value);
- }
- }
- }
抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。抽象类不能实例化,必须通过继承由派生类实现其抽象方 法,因此对抽象类不能使用new 关键字,也不能被密封。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由overriding 方法来实现。
定义方法为:
- /// <summary>
- /// 定义抽象类
- /// </summary>
- abstract public class Animal
- {
- //定义静态字段
- protected int _id;
- //定义属性
- public abstract int Id
- {
- get;
- set;
- }
- //定义方法
- public abstract void Eat();
- //定义索引器
- public string this[int i]
- {
- get;
- set;
- }
- }
- /// <summary>
- /// 实现抽象类
- /// </summary>
- public class Dog: Animal
- {
- public override int Id
- {
- get {return _id;}
- set {_id = value;}
- }
- public override void Eat()
- {
- Console.Write("Dog Eats.")
- }
- }
3.1 相同点
3.2 不同点
通过相同与不同的比较,我们只能说接口和抽象类,各有所长,但无优略。在实际的编程实践中,我们要视具体情况来酌情量才,但是以下的经验和积 累,或许能给大家一些启示,除了我的一些积累之外,很多都来源于经典,我相信经得起考验。所以在规则与场合中,我们学习这些经典,最重要的是学以致用,当 然我将以一家之言博大家之笑,看官请继续。
3.3 规则与场合
以上的规则,我就厚颜无耻的暂定为T14 条吧,写的这么累,就当一时的奖赏吧。大家也可以互通有无,我将及时修订。
4.1 绝对经典
.NET Framework 是学习的最好资源,有意识的研究FCL 是每个.NET 程序员的必修课,关于接口和抽象类在FCL 中的使用,我有以下的建议:
4.2 别样小菜
下面的实例,因为是我的理解,因此给经典打上“ 相对” 的记号,至于什么时候晋升为“ 绝对” ,就看我在.NET 追求的路上,是否能够一如既往的如此执着,因此我将把相对重构到绝对为止(呵呵)。 本示例没有阐述抽象类和接口在设计模式中的应用,因为那将是另一篇有讨论价值的文本,本文着眼与概念和原则的把握,但是真正的应用来自于具体的需求规范。
设计结构如图所示:

1. 定义抽象类
- public abstract class Animal
- {
- protected string _name;
- //声明抽象属性
- public abstract string Name
- {
- get;
- }
- //声明抽象方法
- public abstract void Show();
- //实现一般方法
- public void MakeVoice()
- {
- Console.WriteLine("All animals can make voice!");
- }
- }
2. 定义接口
- public interface IAction
- {
- //定义公共方法标签
- void Move();
- }
3. 实现抽象类和接口
- 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;}
- }
- //实现接口方法
- 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. 客户端实现
- 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();
- }
- }
正所谓真理是大家看出来的,所以将园子里有创新性的观点潜列于此,一是感谢大家的共享,二是完善一家之言的不足,希望能够将领域形成知识,受用于我,受用于众。
最后,MSDN 的建议是:
接口和抽象类,是论坛上、课堂间讨论最多的话题之一,之所以将这个老话题拿出来再议,是因为从我的体会来说,深刻的理解这两个面向对象的基本内 容,对于盘活面向对象的抽象化编程思想至关重要。本文基本概况了接口和抽象类的概念、异同和使用规则,从学习的观点来看,我认为这些总结已经足以表达其核 心。但是,对于面向对象和软件设计的深入理解,还是建立在不断实践的基础上,Scott 说自己每天坚持一个小时用来写Demo ,那么我们是不是更应该勤于键盘呢。对于接口和抽象类,请多用而知其然,多想而知其奥吧。