2009-02-19 12 views
7

He estado consultando la API JMS desde J2EE y encontré un comportamiento extraño en el que ciertos métodos que se declaran en una interfaz (por ejemplo, createQueue en Session) se vuelven a declarar en las subinterfaces como QueueSession y con documentación idéntica.En Java, cuando una interfaz se extiende a otra, ¿por qué se volvería a declarar un método en una subinterfaz?

Dado que una subinterfaz "hereda" todas las declaraciones de métodos de la interfaz que hereda, y como la herramienta JavaDoc no tiene problemas para ordenar los JavaDocs de la subinterfaz y crear una lista de "operaciones heredadas", no puedo entender lo que esto logra

Lo único que se puede pensar es que inicialmente la llamada estaba en Session, y luego se movió a QueueSession cuando se creó la subclase específica, aunque entonces habría esperado ver algo en la documentación de la clase superior. Pero esto es solo conjetura.

Así que la pregunta es: ¿Hay alguna razón convincente para redeclarar un método en una subinterfaz?

Respuesta

13

Habiendo visto esto suceder en alguna ocasión mientras trabajaba para Sun, puedo decirle cómo suele suceder. Alguien define una interfaz, digamos Alice, con algunos métodos; muchos desarrolladores implementan esa interfaz.

Algún tiempo más tarde, se ha dado cuenta de que necesitan alguna otra interfaz, lo llaman Bob, que tiene un subconjunto de los métodos de Alice, con el fin de permitir que sirva como una interfaz de base para otra interfaz, Clara.

Si mueve los métodos de Alicia a Bob, rompe todo el código que implementa Alicia; tienes que volver y al menos recompilar una gran cantidad de código, algunos de los cuales no puedes tener, y por razones políticas no se puede romper.

Así que no es así.

+1

Eso tiene sentido Pero ¿por qué no cambiar los JavaDocs en la superclase y decir algo así como "Hazme un favor, nunca me invoques directamente, cree una instancia de la subinterfaz"? – Uri

+0

Porque seria admitir un error? Más en serio, podría ser que la interfaz superclase * * a veces se usa sola, no hay razón para que una refactorización no pueda ser simplemente eliminar métodos. –

+0

"se da cuenta de que Necesito alguna otra interfaz, llámala Bob, que tiene un subconjunto de los métodos de Alicia "Si todo lo que necesitan es un subconjunto de Alicia, ¿por qué no pueden hacer que Bob sea una interfaz separada con solo unos pocos métodos de Alicia, en lugar de hacer Alice es su superclase? – Jagat

2

Nunca he visto un buen razonamiento para esto. El mejor que he visto es que:

  • Se deja en claro lo que es sin tener que ver el padre
  • Esto hace que sea más fácil cambiar lo que la clase se extiende sin tener que averiguar qué interfaces se debe aplicar

No me gusta ninguna sugerencia. Creo que la causa probable es que, mientras se escribía el código, las interfaces se escribían antes que las clases abstractas y los desarrolladores no se molestaban en eliminar los implementos duplicados.

Nunca subestime la pereza de un desarrollador :-)

Al final no se haga daño a excepción de que en tiempo de carga de clase que probablemente lleva una fracción no apreciable de tiempo más largo para cargar una clase con interfaces duplicadas.

-1

la única razón que conozco es para ampliar la visibilidad de un método (es decir, clonar de protegido a público), pero ese no parece ser el caso aquí.

+0

Eso no es posible con una interfaz. La visibilidad de un método se define por la visibilidad de la interfaz en sí misma. Y no tiene permitido reducir la visibilidad en una subinterfaz. –

+1

me siento corregido :( –

+0

Además, Cloneable no tiene ningún método –

0

Yo diría que no, no hay ninguna razón para hacer esto. Sin embargo, puedo imaginar algunas maneras en que esto podría suceder durante la evolución de algunos códigos. No es raro tomar una interfaz existente y extraer una súper-interfaz más pequeña. En esa circunstancia, puedo imaginarme abandonar la interfaz existente pero simplemente cambiarla para extenderla desde una nueva interfaz.

3

En Java 5 puede cambiar el tipo de devolución de un método de anulación, haciéndolo más específico. Más comúnmente, la documentación es diferente, por lo que el método debe declararse nuevamente.

Sin embargo, si el método y la documentación son los mismos, no es necesario. Sin embargo, verá muchos códigos que no son estrictamente necesarios. Es posible que se haya necesitado una vez, pero algo ha cambiado y ya no es necesario. Es bastante probable que nunca fue necesario, pero se hizo porque el desarrollador pensó que había que hacer algo cuando en realidad no había una buena base para ello.

BTW: Diferentes personas tienen diferentes puntos de vista sobre lo que se necesita o lo que se debe tener para explicárselo.

Cuestiones relacionadas