В Java, когда один интерфейс расширяет другой, зачем переопределять метод в подинтерфейсе? - PullRequest
8 голосов
/ 19 февраля 2009

Я смотрел на JMS API из J2EE и обнаружил странное поведение, когда определенные методы, которые объявлены в интерфейсе (например, createQueue в Session), снова объявляются в подинтерфейсах, таких как QueueSession, и с идентичной документацией.

Поскольку подынтерфейс «наследует» все объявления методов интерфейса, который он наследует, и поскольку у инструмента JavaDoc нет проблем с сортировкой JavaDocs подинтерфейса и созданием списка «унаследованных операций», я не могу понять, что это достигается.

Единственное, о чем можно подумать, это то, что первоначально вызов был в сеансе, а затем был перемещен в QueueSession при создании определенного подкласса, хотя тогда я ожидал увидеть что-то в документации верхнего класса. Но это всего лишь догадка.

Итак, вопрос: Есть ли убедительная причина переопределить метод в подинтерфейсе?

Ответы [ 5 ]

14 голосов
/ 19 февраля 2009

Видя, как это иногда случается во время работы в Sun, я могу рассказать вам, как это обычно происходит. Кто-то определяет интерфейс, скажем, Алису, с некоторыми методами; многие разработчики реализуют этот интерфейс.

Через некоторое время стало понятно, что им нужен какой-то другой интерфейс, назовите его Боб, у которого есть подмножество методов Алисы, чтобы позволить ему служить базовым интерфейсом для другого интерфейса Клара.

Если вы переместите методы Алисы в Боба, вы нарушите весь код, который реализует Алису; вам нужно вернуться назад и, по крайней мере, перекомпилировать целый набор кода, часть которого вам может не принадлежать и по политическим причинам не может сломаться.

Значит, нет.

4 голосов
/ 20 февраля 2009

В Java 5 вы можете изменить тип возвращаемого значения переопределяющего метода, сделав его более конкретным. Чаще всего документация отличается, поэтому метод должен быть объявлен снова.

Однако, если метод и документация совпадают, в этом нет необходимости. Тем не менее, вы увидите много кода, который не нужен строго. Возможно, это было необходимо однажды, но что-то изменилось, так что больше не нужно. Вполне вероятно, что это никогда не было необходимо, но было сделано, потому что разработчик думал, что нужно что-то делать, хотя на самом деле для этого не было хорошей основы.

Кстати: у разных людей разные взгляды на то, что нужно или удобно иметь или лучше сделать явным.

2 голосов
/ 19 февраля 2009

Я никогда не видел веских причин для этого. Лучшее, что я видел, это:

  • Это дает понять, что это такое, не видя родителя
  • Это облегчает изменение того, что расширяет класс, без необходимости выяснять, какие интерфейсы он должен реализовывать

Мне не нравится ни одно предложение. Я думаю, что вероятная причина в том, что во время написания кода интерфейсы были написаны до абстрактных классов, и разработчики не удосужились удалить дублирующиеся реализации.

Никогда не стоит недооценивать лень разработчика: -)

В конце концов, никакого вреда не будет, за исключением того, что во время загрузки класса, вероятно, требуется незаметная доля времени, чтобы загрузить класс с дублирующимися интерфейсами.

0 голосов
/ 19 февраля 2009

Я бы сказал, нет, нет причин делать это. Я могу представить пару способов, как это могло произойти во время эволюции некоторого кода. Нередко можно взять существующий интерфейс и извлечь из него меньший супер-интерфейс. При таких обстоятельствах я могу представить, что оставляю существующий интерфейс, но просто изменяю его, чтобы расширить с нового интерфейса.

0 голосов
/ 19 февраля 2009

Единственная причина, по которой я знаю, - это расширение видимости метода (т.е. клонирование от защищенного к общедоступному), но здесь это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...