为什么抽象类和接口都存在于C#中?

123*_*per 13 .net c# oop

如果我们可以通过将类中的所有成员都设置为抽象来实现接口功能,那么为什么抽象类和接口都存在于C#中.

是因为:

  1. 接口存在多重继承
  2. 有接口是有意义的,因为对象的CAN-DO功能应放在接口而不是基本抽象类中.

请澄清

Jon*_*eet 29

好吧,抽象类可以指定一些实现,但通常不是全部.(已经说过,完全有可能提供一个没有抽象成员的抽象类,但是很多虚拟的抽象类都带有"no-op"实现).接口提供了没有实现,仅仅是一个合同.

你当然可以争辩说,如果允许类的多重继承,接口将毫无意义.

就个人而言,我并没有因为继承而在整个"is-a"vs"can-do"区别.它从来没有给我一个关于做什么的直觉,因为只是玩弄不同的想法,看看哪些人觉得最灵活.(再说一次,我非常喜欢"继承传承"这个家伙......)

编辑:正如在他的评论中反驳lbushkin第三点的最方便的方法......你可以通过密封它来覆盖一个非虚拟的抽象方法(就无法进一步覆盖它而言):

public abstract class AbstractBase
{
    public abstract void Foo();
}

public class Derived : AbstractBase
{
    public sealed override void Foo() {}
}
Run Code Online (Sandbox Code Playgroud)

派生的类Derived不能再覆盖Foo.

我并不以任何方式暗示我想要实现多重继承 - 但是如果我们确实拥有它(以及它的复杂性)那么一个包含抽象方法的抽象类几乎可以完成接口所做的一切.(这是显式接口实现的问题,但这是我现在所能想到的.)

  • "如果允许类的多重继承,接口将毫无意义".我不同意这种说法.首先,接口提供了一定程度的解耦,即使是完全由虚拟无操作方法提供的纯抽象基类也无法提供.它们有助于将类型的合同义务与不可避免的以实现为中心的问题分开.其次,由于接口没有数据成员,因此它们避免了数据的钻石继承问题.第三,C#允许实现接口的方法是非虚拟的(这可能很有用) - 抽象类不允许. (2认同)

zeb*_*box 16

这不是一个微不足道的问题,这是一个非常好的问题,我总是问我采访的任何候选人.
简而言之 - 抽象基类定义类型层次结构,而接口定义合同.

你可以看到它是一个 vs 实现一个.
ie Account可以是一个抽象的基本帐户,因为你可以拥有一个从抽象基类派生的a CheckingAccount,a SavingsAccountAccount.抽象基类也可以包含非抽象方法,属性和字段,就像任何普通类一样.但是,接口包含必须实现的抽象方法和属性.

c#let你只从一个基类派生 - 单继承就像java一样.但是,您可以根据需要实现任意数量的接口 - 这是因为接口只是您的类承诺实现的合同.

因此,如果我有一个班级,SourceFile那么我的班级可以选择实施ISourceControl"我忠实承诺实施所需的方法和属性ISourceControl"

这是一个很大的领域,可能比我给我的更好,但我的时间很短,但我希望有所帮助!


And*_*are 8

它们都存在,因为它们都是非常不同的东西.抽象类允许实现,而接口则不允许.界面非常方便,因为它允许我说出我正在构建的类型(它是可序列化的,可食用的等),但它不允许我为我定义的成员定义任何实现.

抽象类比某个界面更强大,它允许我通过抽象和虚拟成员创建继承接口,但如果我选择的话,还提供某种默认或基本实现.然而,正如蜘蛛侠所知道的那样,由于抽象类在架构上更加脆弱,因此强大的力量带来了巨大的责任.

旁注:值得注意的是Vance Morrrison(CLR团队)推测在未来版本的CLR中向接口添加默认方法实现.这将极大地模糊接口和抽象类之间的区别.有关详情,请参阅此视频.