在 Java 中,当一个接口扩展另一个接口时,为什么要在子接口中重新声明方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/563952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:52:34  来源:igfitidea点击:

In Java when one interface extends another, why would one redeclare a method in a subinterface?

javainterface

提问by Uri

I've been looking at the JMS API from J2EE and found a strange behavior where certain methods that are declared in an interface (e.g., createQueue in Session) are declared again in the subinterfaces such as QueueSession, and with identical documentation.

我一直在查看 J2EE 的 JMS API,发现了一种奇怪的行为,其中在接口中声明的某些方法(例如,Session 中的 createQueue)在子接口(例如 QueueSession)中再次声明,并且具有相同的文档。

Since an subinterface "inherits" all the method declarations of the interface it inherits, and since the JavaDoc tool has no problem sorting out the JavaDocs of the subinterface and creating an "inherited operations" list, I can't figure out what this achieves.

由于子接口“继承”了它继承的接口的所有方法声明,而且由于JavaDoc工具可以毫无问题地整理子接口的JavaDoc并创建“继承操作”列表,因此我无法弄清楚这实现了什么。

The only think of is that initially the call was in Session, and then moved to QueueSession when the specific subclass was created, though then I would have expected to see something in the documentation of the upperclass. But this is just conjecture.

唯一想到的是最初调用是在 Session 中,然后在创建特定子类时移动到 QueueSession ,尽管那时我本来希望在上层类的文档中看到一些东西。但这只是推测。

So the question is: Is there a convincing reason to redeclare a method in a subinterface?

所以问题是:是否有令人信服的理由在子接口中重新声明方法?

回答by Charlie Martin

Having seen this happen on occasion while working for Sun, I can tell you how it usually happens. Someone defines an interface, let's say Alice, with some methods; many developers implement that interface.

在为 Sun 工作时偶尔会发生这种情况,我可以告诉您它通常是如何发生的。有人定义了一个接口,比如 Alice,有一些方法;许多开发人员实现了该接口。

Some time later, it's realized that they need some other interface, call it Bob, that has a subset of the methods of Alice, in order to allow it to serve as a base interface for anotherinterface, Clara.

一段时间后,人们意识到他们需要一些其他接口,称为 Bob,它具有 Alice 的方法的子集,以便允许它作为另一个接口 Clara的基本接口。

If you move the methods of Alice into Bob, you break all the code that implements Alice; you have to go back and at least recompile a whole bunch of code, some of which you may not own, and for political reasons can't break.

如果你把 Alice 的方法移到 Bob 中,你就破坏了所有实现 Alice 的代码;你必须回去至少重新编译一大堆代码,其中一些你可能不拥有,而且出于原因不能破坏。

So you don't.

所以你没有。

回答by Peter Lawrey

In Java 5 you can change the return type of a overriding method, by making it more specific. More commonly the documentation is different so the method has to be declared again.

在 Java 5 中,您可以通过使其更具体来更改覆盖方法的返回类型。更常见的是,文档是不同的,因此必须再次声明该方法。

However if the method and documentation are the same, there is no need for it. However, you will see plenty of code which isn't strictly needed. It is possible it was needed once, but something was changed so it is no longer needed. It is quite likely that it was never needed but was done because the developer thought something needed to be done when actually there wasn't a good basis for it.

但是,如果方法和文档相同,则不需要。但是,您会看到大量并非严格需要的代码。有可能它曾经需要过一次,但是有些东西已经改变了,所以不再需要它了。很可能从来不需要它,而是因为开发人员认为需要做某事,而实际上并没有很好的基础。

BTW: Different people have different views of what is needed or handy to have or better to make explicit.

顺便说一句:不同的人对需要或方便拥有或更好地明确表达的内容有不同的看法。

回答by TofuBeer

I have never seen a good reasoning for this. The best I have seen is that:

我从来没有见过一个很好的理由。我见过的最好的是:

  • It makes it clear what it is without having to see the parent
  • It makes it easier to change what the class extends without having to figure out what interfaces it should implement
  • 它清楚地表明它是什么而无需看到父母
  • 它可以更轻松地更改类扩展的内容,而无需弄清楚它应该实现哪些接口

I don't like either suggestion. I think the likely cause is that while the code was being written the interfaces were written before the abstract classes and the developers didn't bother to remove the duplicate implements.

我不喜欢任何一个建议。我认为可能的原因是在编写代码时接口是在抽象类之前编写的,开发人员没有费心删除重复的实现。

Never underestimate the laziness of a developer :-)

永远不要低估开发人员的懒惰:-)

In the end no harm is done except that at class load time it probably takes a non-noticeable fraction of time longer to load a class with duplicate interfaces.

最后,除了在类加载时加载具有重复接口的类可能需要更长的时间,这并没有造成任何伤害。

回答by Alex Miller

I would say no, there is no reason to do this. I can imagine a couple ways this could happen during the evolution of some code though. It's not uncommon to take an existing interface and pull a smaller super-interface out of it. In that circumstance, I can imagine leaving the existing interface but just changing it to extend from a new interface.

我会说不,没有理由这样做。不过,我可以想象在某些代码的演变过程中可能会发生这种情况的几种方式。采用现有接口并从中拉出较小的超级接口的情况并不少见。在那种情况下,我可以想象离开现有的界面,而只是将其更改为从新界面扩展。

回答by Ray Tayek

the only reason i know of is to widen the visibility of a method (i.e. clone from protected to public), but that does not seem to be the case here.

我知道的唯一原因是扩大方法的可见性(即从受保护的克隆到公共的),但这里似乎并非如此。