接口与抽象类

149
在C#中,何时应该使用接口,何时应该使用抽象类?可以决定因素是什么?
4个回答

162

更新:C# 8.0 新特性: 从 C# 8.0 开始,接口可以为成员(包括属性)定义默认实现。在接口中为属性定义默认实现很少见,因为接口可能不定义实例数据字段。

抽象类的优点是:

  • 能够指定方法的默认实现
  • 增加函数的不变式检查
  • 在“接口”方法被调用时具有稍微更多的控制权
  • 能够免费提供与接口相关或无关的行为

接口仅仅是数据传递的契约,并且没有这些功能。然而,它们通常更灵活,因为一个类型只能派生自一个类,但可以实现任意数量的接口。


@JaredPar:我猜这是为了打击回答重复问题的行为(顺便说一下,我不是那个给你投票负面评价的人) - Brann
18
@Brann,很不幸我以前看到过这种行为。在我看来,对原帖进行投反对票似乎更合理。查找重复帖子是原帖作者的责任。 - JaredPar
3
我很惊讶这个答案获得了那么多赞同并被接受为正确答案。它似乎展示了回答者对抽象类的偏见(列出四点“抽象类的优点”,然后是“接口只是”和一个单独的“然而”支持接口),而不是真正描述抽象类和接口之间的区别。我并不是要攻击回答者,但显然这个问题应该以更客观的方式陈述,以最好地回答这个问题。 - Matthew
4
我认为这个回答提供了抽象类和接口的所有相关事实,所以为什么它不是客观的呢?我认为这是一个非常好的回答。 - Gigi
@Guffa的回答更好,因为它正确地解释了何时应该使用每个选项。 - James Z.

118

抽象类和接口在语义上是不同的,尽管它们的用法可能有重叠。

抽象类通常被用作相似类的构建基础。适用于这些类的共同实现可以在抽象类中体现。

接口通常用于指定类的能力,这些类不必非常相似。


13

另一个需要考虑的问题是,由于没有多重继承,如果想让一个类实现/继承你的接口/抽象类,但又要继承另一个基类,那么就应该使用接口。


让我不同意你对这个句子的看法(但是继承自另一个基类,使用接口)。因为继承=可重用性。一般来说,接口并不涵盖可重用性。当我们谈论可重用性时,必须有一个实现,而在接口中我们没有实现。这就是为什么接口不适用于多重继承的原因。 - Behnam

10

真正的问题是:使用接口还是基类。这个问题以前已经讨论过。

在C#中,抽象类(用"abstract"关键字标记的类)仅仅是一个不能实例化对象的类。这与仅仅区分基类和接口的目的不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接