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

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

接口:

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

抽象类:

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

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

另请参阅:

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


当前回答

对于.Net,

你对第二位面试官的回答也是对第一位的回答。。。抽象类可以有实现,AND状态,接口不能。。。

编辑:另一方面,我甚至不会使用短语“subclass”(或“继承”短语)来描述“定义为实现”接口的类。对我来说,接口是一个合约的定义,如果类被定义为“实现”该接口,那么它必须遵守该定义。它没有继承任何东西。。。你必须自己明确地添加所有内容。

其他回答

从编码角度

如果抽象类只有抽象方法,则接口可以替换抽象类。否则,将抽象类更改为接口意味着您将失去继承提供的代码重用性。

从设计角度

如果它是“Is a”关系,并且您需要一个子集或所有功能,请将其保留为抽象类。如果是“应该做”的关系,请将其保留为界面。

决定你需要什么:只是策略执行,或者代码重用和策略。

从概念上讲,保持特定于语言的实现、规则、好处,并通过使用任何人或两者实现任何编程目标,可以或不可以有代码/数据/属性等等,单继承或多继承等等

1-抽象(或纯抽象)类旨在实现层次结构。如果您的业务对象在结构上看起来有些相似,仅表示父子(层次结构)类型的关系,那么将使用继承/抽象类。如果您的业务模型没有层次结构,那么就不应该使用继承(这里我不是在谈论编程逻辑,例如一些设计模式需要继承)。从概念上讲,抽象类是一种在OOP中实现业务模型层次结构的方法,它与接口无关,实际上将抽象类与接口进行比较是没有意义的,因为两者在概念上完全不同,在访谈中要求它只是为了检查概念,因为当涉及到实现时,它看起来都提供了一些相同的功能,而我们程序员通常更强调编码。[请记住,抽象与抽象类不同]。

2-接口是一个契约,一个由一组或多组功能表示的完整业务功能。这就是它被实现而不是继承的原因。业务对象(是否是层次结构的一部分)可以具有任意数量的完整业务功能。它与抽象类无关,通常意味着继承。例如,人可以跑步,大象可以跑步,鸟可以跑步等等,所有这些不同层次的对象都将实现RUN接口或EAT或SPEAK接口。不要进入实现,因为您可能会将其实现为为实现这些接口的每种类型提供抽象类。任何层次结构的对象都可以具有与其层次结构无关的功能(接口)。

我相信,接口的发明并不是为了实现多重继承或公开公共行为,类似地,纯抽象类并不是为了推翻接口,而是接口是一个对象可以实现的功能(通过接口的功能),抽象类代表一个层次结构的父级,以生成具有父级核心结构(属性+功能)的子级

当你被问到差异时,这实际上是概念上的差异,而不是特定语言实现中的差异,除非被明确问到。

我相信,两位面试官都希望这两者之间有一条直线的直接区别,当你失败时,他们试图通过将“一个作为另一个”来驱使你实现这一区别

如果你有一个只有抽象方法的抽象类呢?

其他一些区别:

抽象类可以有静态方法、财产、字段等,而操作符和接口则不能。强制转换运算符允许向抽象类强制转换,但不允许向接口强制转换。

所以,即使抽象类从未实现(通过它的静态成员),也可以单独使用抽象类,并且不能以任何方式单独使用接口。

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

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

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

接口:如果您希望在组件上暗示规则,则应使用该接口彼此相关的

赞成的意见:

允许多重继承通过不公开上下文中使用的确切类型的对象来提供抽象通过合同的特定签名提供一致性

欺骗:

必须执行所有定义的合同不能有变量或委托一旦定义,就不能在不破坏所有类的情况下进行更改

抽象类:应用于希望对彼此相关的组件具有一些基本或默认行为或实现的情况

赞成的意见:

比接口更快在实施中具有灵活性(您可以完全或部分实施)可以在不破坏派生类的情况下轻松更改

欺骗:

无法实例化不支持多重继承