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

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

由于子接口“inheritance”它inheritance的接口的所有方法声明,并且由于JavaDoc工具在排序子接口的JavaDocs并创建“inheritance的操作”列表时没有问题,因此我无法弄清楚它实现了什么。

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

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

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

一段时间后,它意识到他们需要一些其他接口,称之为Bob,它有Alice的一部分方法,以便它可以作为另一个接口的基本接口,Clara。

如果将Alice的方法移动到Bob中,则会破坏实现Alice的所有代码; 你必须回去并至少重新编译一大堆代码,其中一些你可能不拥有,并且出于政治原因不能破解。

所以你没有。

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

但是,如果方法和文档相同,则不需要它。 但是,您将看到大量不严格需要的代码。 它可能需要一次,但有些东西被改变,因此不再需要它。 它很可能永远不需要,但之所以这样做是因为开发人员认为在实际上没有一个好的基础时需要做些什么。

顺便说一句:不同的人对于需要什么或者有什么需要有不同的看法,或者更好地做出明确的看法。

我从来没有见过这样的好理由。 我见过的最好的是:

  • 它清楚地表明它是什么而不必看父母
  • 它可以更容易地更改类的扩展,而无需弄清楚它应该实现什么接口

我不喜欢这两个建议。 我认为可能的原因是,在编写代码时,接口是在抽象类之前编写的,开发人员并不打算删除重复的工具。

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

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

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

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