我最近接受了两次电话采访,被问及接口类和抽象类之间的区别。我已经解释了我能想到的每一个方面,但似乎他们在等我提一些具体的事情,我不知道是什么。

根据我的经验,我认为以下是正确的。如果我遗漏了一个要点,请告诉我。

接口:

接口中声明的每个方法都必须在子类中实现。接口中只能存在事件、委托、财产(C#)和方法。一个类可以实现多个接口。

抽象类:

子类只能实现抽象方法。抽象类可以具有具有实现的普通方法。除了事件、委托、财产和方法之外,抽象类还可以有类变量。由于C#中不存在多重继承,一个类只能实现一个抽象类。

在这之后,面试官提出了一个问题:“如果你有一个只有抽象方法的抽象类呢?这和接口有什么不同?”我不知道答案,但我认为这是上面提到的继承,对吧?另一位面试官问我,“如果你在接口中有一个公共变量,那会和抽象类中有什么不同?”我坚持认为你不能在接口中使用公共变量。我不知道他想听什么,但他也不满意。

另请参阅:

何时使用接口而不是抽象类,反之亦然接口与抽象类如何决定使用抽象类和接口?接口和抽象类之间的区别是什么?


当前回答

虽然这个问题很老,但我想补充一点,支持接口:

可以使用任何依赖注入工具来注入接口,其中作为抽象类注入的支持很少。

其他回答

面试官们正在寻找一棵奇怪的树。对于像C#和Java这样的语言,这是有区别的,但在其他语言中,像C++没有区别。OO理论并没有区分这两者,仅仅是语言的语法。

抽象类是一个同时具有实现和接口(纯虚拟方法)的类,将被继承。接口通常没有任何实现,只有纯虚拟函数。

在C#或Java中,没有任何实现的抽象类与接口的区别仅在于用于从其继承的语法以及只能从其中继承的事实。

从我的另一个答案来看,主要是关于何时使用一个而不是另一个:

根据我的经验,界面是最好的有几个类时使用每个都需要对相同的方法,以便可由其他代码互换使用将针对这些类的公共接口。最好的当协议很重要,但底层逻辑可能不同于每个类别。如果你不是复制逻辑,考虑抽象类或标准类继承相反

Jeffrey Richter通过C#从CLR复制。。。

我经常听到这样一个问题,“我应该设计一个基类型还是一个接口?”答案并不总是清晰明了。

以下是一些可能对您有所帮助的指南:

■■ IS-A与CAN-DO关系A类型只能继承一个实现。如果导出类型不能声明与基类型的IS-A关系,不要使用基类型;使用接口。接口意味着CAN-DO关系。如果CAN-DO功能似乎属于对于各种对象类型,使用接口。例如,类型可以转换自身的实例类型可以将其自身的实例序列化(ISerializable),注意,值类型必须从System.ValueType派生,因此不能可以从任意基类派生。在这种情况下,您必须使用CAN-DO关系并定义接口。

■■ 易用性作为开发人员,定义从基类型,而不是实现接口的所有方法。基本类型可以提供许多功能,因此派生类型可能只需要对其行为进行相对较小的修改。如果提供接口,则新类型必须实现所有成员。

■■ 一致的实施无论接口合同记录得多么好每个人都不可能100%正确地履行合同。事实上,COM这就是为什么某些COM对象只能与微软Word或Windows Internet Explorer。通过为基础类型提供默认实现,您首先使用一种有效且经过良好测试的类型;那么你可以修改需要修改的零件。

■■ 版本控制如果向基类型添加方法,则派生类型继承新方法,您开始使用一种有效的类型,用户的源代码甚至不必重新编译。向接口添加新成员将强制接口的继承者更改它的源代码并重新编译。

虽然这个问题很老,但我想补充一点,支持接口:

可以使用任何依赖注入工具来注入接口,其中作为抽象类注入的支持很少。

抽象类不是纯抽象的,因为它是具体(实现的方法)和未实现的方法的集合。但是接口是纯抽象的,因为只有未实现的方法,而没有具体的方法。

还有一个区别是

抽象类允许您创建子类可以实现或覆盖的功能。接口只允许您定义功能,而不允许实现它。

何时使用抽象类

如果用户希望为所有对象编写通用功能。抽象类是未来重新实现的最佳选择,它可以在不影响最终用户的情况下添加更多功能。

何时使用接口

如果用户希望编写不同的功能,则对象上的功能将不同。接口是最好的选择,如果接口发布后不需要修改需求。