如果我们可以通过将类中的所有成员都设置为抽象来实现接口功能,那么为什么抽象类和接口都存在于C#中.
是因为:
请澄清
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.
我并不以任何方式暗示我想要实现多重继承 - 但是如果我们确实拥有它(以及它的复杂性)那么一个只包含抽象方法的抽象类几乎可以完成接口所做的一切.(这是显式接口实现的问题,但这是我现在所能想到的.)
zeb*_*box 16
这不是一个微不足道的问题,这是一个非常好的问题,我总是问我采访的任何候选人.
简而言之 - 抽象基类定义类型层次结构,而接口定义合同.
你可以看到它是一个 vs 实现一个.
ie
Account可以是一个抽象的基本帐户,因为你可以拥有一个从抽象基类派生的a CheckingAccount,a SavingsAccount等Account.抽象基类也可以包含非抽象方法,属性和字段,就像任何普通类一样.但是,接口仅包含必须实现的抽象方法和属性.
c#let你只从一个基类派生 - 单继承就像java一样.但是,您可以根据需要实现任意数量的接口 - 这是因为接口只是您的类承诺实现的合同.
因此,如果我有一个班级,SourceFile那么我的班级可以选择实施ISourceControl"我忠实承诺实施所需的方法和属性ISourceControl"
这是一个很大的领域,可能比我给我的更好,但我的时间很短,但我希望有所帮助!