如果我实现一个接口,它称为继承吗?


31

如果我的课程implements有接口,那么我可以说我正在继承吗?我知道当一个类是extends另一个类时,它就是继承。



7
乔德雷尔的评论是完全错误的。实现接口确实是继承,而从另一个接口继承一个接口就是继承。我们怎么知道?通过定义我们正在使用的单词。继承是一种类型的可继承成员同时也是另一种类型的成员的属性。按照这个定义,很明显,实现接口的类继承了接口的所有方法;只需查看类和接口,您就会发现在正确的程序中它们具有相同的成员。
埃里克·利珀特

我没有检查,留下了更多的困惑。
RajeeV VenkaT 2016年

18
对于它的价值,我认为您在单词定义上花了很多时间,这并不会给您带来很多好处。归根结底,我们都知道实现接口的含义,以及是否将其视为“继承性”对您的日常工作基本上无关紧要。
罗伯特·哈维

3
我(大部分)同意罗伯特的观点。我认为,了解各种术语中使用的术语的确切技术含义具有真正的价值。但是罗伯特是对的,理解实际影响将带来更大的好处!如何使用继承使代码更安全?更可测试?更可重用?更灵活?等等。知道基本类型的成员也是派生类型的成员是很好的,但是最好还是知道如何有效地使用它。
埃里克·利珀特

Answers:


78

更新:我已经修改了这个答案。值得大声疾呼的评论中提出了许多优点。

如果我的课程实现了接口,那么我可以说我正在继承吗?

“继承”是什么意思还不清楚。让我们问一个稍微不同的问题吗?

什么是继承?

  • 当一种类型X的成员被视为另一种类型Y的成员时,Y的那些成员将从X继承
  • 某些类型之间存在继承关系。也就是说,对于某些X和Y类型,我们说“ Y从X继承”。

这些有细微的不同。不幸的是,因为这令人困惑。

这种微妙的区别通常会引起什么混乱?

因为人们将继承视为共享实现细节的机制,所以可能会造成混乱。尽管这一种机制,但是该机制通过共享成员起作用。这些成员不需要实现!正如我们将看到的,它们可以是抽象的。

如果Java和C#规范使用“继承”以外的词来描述接口方法和类之间的关系,以避免这种混淆,我个人会更高兴。但他们不这样做,我们必须理性,从规格,而不是反对他们。

在Java中,接口成员是否由实现它们的类继承?

是的,有些。请参阅Java规范第8.4.8节,为方便起见,在此引用。

类C从其直接超类和直接超接口继承所有满足以下所有条件的抽象方法和默认方法m:[...]

如果您说一个类实现了一个接口,则该类将继承该接口的抽象方法和默认方法。(当然,我省略了下面的条件;有关详细信息,请参见规范。特别是,实现接口的成员的类被视为已继承该成员。这再次令人困惑吗?是。)

我们通常在Java中说类是从接口继承的吗?

通常,我们会说一个类实现一个接口。如上所述,类可以从接口继承成员,但仍不能说是从接口继承。是的,这令人困惑。

这种微妙的区别在日常工作中是否重要?

通常不会。规范的这种狭窄的解析对编译器编写者比业务开发人员更有用。理解何时使用接口比获得“继承自”的精确定义更为重要。


4
我不能与规范的参考。当规范不同时,正如它们必然会做的那样,简单的术语在语义上会变得超载,并且在上下文之外变得模棱两可。用这个问题加上标签,java所以这是正确的答案,除非OP意味着其他java:-)
Jodrell

5
尽管问题是用Java标记的,但我发现引用通用术语的语言规范还是有问题的。许多语言都有接口,它们的语言规范可能使用不同的术语,因此在与使用X-Lang的开发人员交谈时,使用特定于Java的术语可能会造成混淆。
托马斯·欧文斯

5
@ThomasOwens:我同意这种情况很普遍,我完全不同意你的结论。您描述的沟通问题的解决方案是教育每个参与者有关单词在相关上下文中的确切含义。存在规范以提供这种清晰度。使用它们!
埃里克·利珀特

5
为什么Java语言规范在这里有最终决定权?语言规范通常声称“通用开发人员”不同意术语。
本杰明·格伦鲍姆

5
@BenjaminGruenbaum:我不知道。这些开发人员是错误的,他们经常承担起“教育”他人错误信念的责任。您不会相信我必须解决的编程语言书籍的数量,因为作者对VB,C#,JavaScript等有一些完全疯狂的信念,这些想法绝对是不正确的。(Jon Skeet不在其中; C#In Depth从一开始就是正确的!我从未对一本书发表过如此少的评论,但仍然得到了报酬。)
Eric Lippert 2016年

26

继承意味着为超类编写新的子类。针对接口编写新类将实现该接口。(并基于旧接口编写新接口将扩展该接口。)

适用于所有三种可能性的唯一正确术语是子类型化。并非每个子类型都是一个子类。


1
GoF的书似乎考虑接口继承适当的词来形容子类型(第1.6类与接口继承)
蚊蚋

“我曾经参加过Java用户组会议,詹姆斯·戈斯林(Java的发明者)是主要发言人。在令人难忘的问答环节中,有人问他:“如果您可以再做一次Java,您会改变什么?”他回答说。他解释说,真正的问题不是类本身,而是实现继承(扩展关系)。接口继承(实现关系)是可取的。您应尽可能避免实现继承。” javaworld.com/article/2073649/core-java/…–
ricardoramos

1

有了子类,您

  • 继承超类的状态(所有实例变量,无论是否看到它们)
  • 继承实际的实现(所有非抽象方法)

使用interfaces,可以通过实现声明的方法来完全履行合同。

这是经典的观察方式。现在,在Java 8中,接口变成了混合接口:

  • 您仍然不继承状态(因为接口仍然没有实例变量)
  • 您现在可以从界面继承默认实现

是否将实现所有方法都具有默认实现的接口仍然算作“实现”,还是算作扩展?我不知道 由于这种情况牵强附会(这实际上启用了无状态多继承),因此我仍将“继承”仅用于子类。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.