接口还是抽象类?
接口还是抽象类?
对于我的新宠物项目,我有一个关于设计的问题,决定已经做出,但我也希望得到一些其他意见。
我有两个类(简化):
class MyObject { string name {get;set;} enum relation {get;set;} int value {get;set;} } class MyObjectGroup { string name {get;set;} enum relation {get;set;} int value {get;set;} List myobjects {get;set;} }
在项目后期,`MyObjectGroup`和`MyObject`应该被平等使用。为此,我可以采取两种方法:
- 创建一个接口:`IObject`
- 创建一个抽象类:`ObjectBase`
我决定采用接口的方式,这样我以后在代码中不必每次都写ObjectBase
,只需写IObject
即可,这样更加方便-但是,这种做法还有其他的优点吗?
其次,将`IXmlSerializable`添加到整个故事中如何?让接口从`IXmlSerializable`继承,还是在抽象基类中实现`IXmlSerializable`更有优势呢?
以下是接口和抽象类之间的一些区别。
1A. 一个类可以继承(实现)一个或多个接口。因此,在C#中,接口用于实现多重继承。
1B. 一个类只能继承一个抽象类。
2A. 接口不能提供任何代码,只有签名。
2B. 抽象类可以提供完整的、默认的代码和/或必须被覆盖的细节。
3A. 接口不能为子例程、函数、属性等提供访问修饰符,一切都默认为public。
3B. 抽象类可以包含子例程、函数、属性的访问修饰符。
4A. 接口用于定义类的外围能力。例如,一个Ship
和一个Car
可以实现一个IMovable
接口。
4B. 抽象类定义类的核心身份,因此被用于对象。
5A. 如果各种实现只共享方法签名,则最好使用接口。
5B. 如果各种实现都是同一种类型,并且使用常见的行为或状态,则最好使用抽象类。
6A. 如果我们向接口添加一个新方法,则必须追踪所有接口的实现并为新方法定义实现。
6B. 如果我们向抽象类添加一个新方法,则可以选择提供默认实现,因此所有现有代码可能正常工作。
7A. 接口不能定义字段。
7B. 抽象类可以定义字段和常量。
8A. 接口不能有构造器。
8B. 抽象类可以实现默认构造器。
9A. 接口只能继承其他接口。
9B. 抽象类可以继承接口、抽象类甚至类。