该篇引用 CLR via C# 中的13.11节。

  应该设计基类还是接口,这个问题不能一概而论,下面提供一些指导性原则:

  1. IS_A关系(指属于,例如汽车属于交通工具) vs CAN_DO关系(指能做某事,例如一个类型能将自己的实例转换另一个类型)  类型只能继承一个实现。如果派生类型不具有与基类的IS_A关系,就不应使用基类,而应该使用接口。接口意味着CAN_DO关系。如果多种对象类型都具有CAN_DO功能,就使用接口。例如,一个类型能将自己的实例转换成另一个类型,一个类型能序列化自己的实例等。注意,值类型必须从System.ValueType派生,所有他们不能从任何基类派生。这种情况下,必须使用一个CAN_DO关系,并定义一个接口;

  2. 易于使用  对开发人员而言,定义一个从基类派生的新类型通常比实现一个接口的所有方法容易得多。基类型可提供大量功能,所有派生类型可能只需要针对其行为稍作改动。如果提供接口,新类型必须实现所有成员;

  3. 一致性的实现  不管一个接口的契约文档做得有多好,都无法保证任何人都能百分之百地正确实现它。事实上,COM颇受这个问题之累,这个问题导致有的COM对象只能正确用于Microsoft Office Word。如果为基类型提供了一个良好的默认实现,那么一开始使用的就是一个正常工作并进行了良好测试的类型,以后只需要根据自己的需要进行修改;

  4. 版本控制  向基类添加一个方法,派生类将继承新方法。一开始使用的就是一个能正常工作的类型,用户的源代码甚至不需要重新编译。向接口添加一个新成员,会强迫接口的继承者更改其源代码并重新编译。

  也可以同时提供接口,及实现了该接口的基类。