2010-10-20 11 views
20

Acabo de buscar la interfaz Set y encontré que la mayoría (o completamente) solo redeclara funciones que ya están en la interfaz Collection. Set se extiende a sí mismo Collection, por lo que no significa que la interfaz Set tiene automáticamente todas las funciones de Collection? Entonces, ¿por qué se vuelven a declarar?Java: establecer la interfaz y las diferencias de interfaz de colección

Por ejemplo, Set redeclares esto:

/** 
* Returns the number of elements in this set (its cardinality). If this 
* set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns 
* <tt>Integer.MAX_VALUE</tt>. 
* 
* @return the number of elements in this set (its cardinality) 
*/ 
int size(); 

/** 
* Returns <tt>true</tt> if this set contains no elements. 
* 
* @return <tt>true</tt> if this set contains no elements 
*/ 
boolean isEmpty(); 

y la Declaración de Collection:

/** 
* Returns the number of elements in this collection. If this collection 
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns 
* <tt>Integer.MAX_VALUE</tt>. 
* 
* @return the number of elements in this collection 
*/ 
int size(); 

/** 
* Returns <tt>true</tt> if this collection contains no elements. 
* 
* @return <tt>true</tt> if this collection contains no elements 
*/ 
boolean isEmpty(); 

esto parece muy redundante para mí. ¿Por qué no acaba de definir la interfaz Set como:

public interface Set<E> extends Collection<E> {} 

Creo que no hay ninguna diferencia entre esas interfaces sola, ¿verdad?


Por supuesto que no estoy pidiendo acerca de la semántica diferente/significado de Set. Yo sé eso. Solo estoy preguntando si técnicamente (es decir, el compilador) tiene alguna diferencia. Es decir, en términos generales:

interface A { void foo(); } 
interface B extends A { void foo(); } 
interface C extends A {} 

Ahora, ¿hay alguna diferencia entre A, B o C?


Si bien el contrato (es decir, lo que se dice en la documentación) en realidad puede ser diferente para algunas funciones (como por add), hay una razón válida para redeclararlas: Para ser capaz de poner una nueva documentación, es decir, para definir el nuevo contrato. No hay funciones (como isEmpty) que tengan exactamente la misma documentación/contrato. ¿Por qué también son redeclarados?

+1

¡Iniciaré una huelga de hambre hasta que esto haya sido resuelto! – willcodejavaforfood

+0

tiene que entender que la interfaz no es una bala de plata. en la interfaz no se puede entender la secuencia, ni la invariante que haya tenido cualquier clase en java. este problema es un problema abierto que los desarrolladores de Java decidieron resolver indicando la respuesta en el manual. si tiene una mejor solución, de representar en lenguaje syntex el sequnce y invariantes, aquí hay un lugar para indicarlo. – none

+0

@none: Bueno, esto no es exactamente a lo que me dirigía con mi pregunta, pero esta es de hecho otra pregunta muy interesante. He visto algunas propuestas en las que era posible escribir condiciones previas y posteriores lógicas complejas para las funciones. Aunque ya no recuerdo exactamente cómo se llamaba. – Albert

Respuesta

11

Técnicamente para el compilador no hace ninguna diferencia.

Sin embargo, un conjunto no puede tener entradas duplicadas, mientras que una colección puede. Esto vale la pena saberlo.

Debido a esto, la semántica de los métodos para los parámetros, los valores de retorno y lo que sucede puede significar cosas diferentes. Redeclar también permite que el javadoc se vuelva más específico.Por ejemplo, para sumar():

Conjunto: @ return true si este conjunto no contiene ya el elemento especificado

Colección: @return true si esta colección ha cambiado como resultado de la llamada

El significado para el conjunto es más específico.

Incluso para los métodos que no son más específicos, permite que el javadoc sea más agradable. Por ejemplo, para size(): "Devuelve la cantidad de elementos en este conjunto (su cardinalidad)". que está más cerca del lenguaje que la gente usa para los conjuntos matemáticos lo entenderá.

Los documentos API resumen esto diciendo: "La interfaz Set establece estipulaciones adicionales, además de las heredadas de la interfaz Collection, en los contratos de todos los constructores y en los contratos de los métodos add, equals y hashCode. otros métodos heredados también se incluyen aquí para su comodidad. (Las especificaciones que acompañan a estas declaraciones se han adaptado a la interfaz Set, pero no contienen ninguna estipulación adicional). "

+0

No creo que esta sea la pregunta. La pregunta era por qué se vuelven a declarar métodos idénticos (como 'size' y' isEmpty'). – musiKk

+0

@musiKk - gracias, pensé que había mencionado eso, pero he tratado de ser más específico ahora –

+1

Ah, entonces, las razones principales (para la mayoría de las funciones) y la respuesta básica a mi pregunta es: "habilita el javadoc para ser más agradable ":) Eso es lo que he asumido, pero pregunté aquí en SO solo para estar seguro de eso. – Albert

9

La respuesta está en la API java6 para el conjunto.

"La interfaz Set establece estipulaciones adicionales, además de las heredadas de la interfaz Collection, en los contratos de todos los constructores y en los contratos de los métodos add, equals y hashCode. Las declaraciones para otros métodos heredados también se incluyen aquí para su conveniencia . (Las especificaciones que acompañan a estas declaraciones se han adaptado a la interfaz Set, pero no contienen ninguna estipulación adicional). "

+0

Ah, de alguna manera ha leído esto. Pero solo para aclarar: ¿Técnicamente, no hace ninguna diferencia?¿Es solo que los IDEs muestran la documentación algo diferente de algunas de las funciones para el desarrollador? – Albert

+0

@Albert lo que no hace ninguna diferencia? Hay cada diferencia en el mundo porque la semántica de Set es diferente de que la semántica de Colección es diferente a la semántica de Lista y así sucesivamente ... – hvgotcodes

+0

@hvgotcodes: diferencia técnica = código de trabajo existente se rompería si usa mi definición 'Set' – Albert

6

Hay más en un método que su firma.

En este caso, la documentación de estos métodos se ha adaptado a los conjuntos, en términos de condiciones previas y posteriores, y la terminología.

+1

+1 para "Hay más en un método que su firma". –

2

Se redecienden porque, incluso si los nombres son iguales, tienen un significado diferente. El método add en el Set es una implementación específica del método genérico add en Collection.

La intención es especificar explícitamente que el método add os Set es muy diferente del método add de Collection.

Por qué no sólo definen la interfaz Establecer como:

public interface Set<E> extends Collection<E> {} 

Si se ha hecho de esta manera, no habría lugar donde el contrato de un Set se puede especificar. ¿Cómo puedo saber que al implementar el método add del Set, no debería permitir duplicados?

+0

Pero el contrato es solo documentación, ¿verdad? Entonces, técnicamente, ¿no haría ninguna diferencia? ¿Es solo que otros desarrolladores conocen el significado diferente? – Albert

+0

_Technically_, visto como código puro, no hay ninguna diferencia. _Es solo que otros desarrolladores saben sobre el significado diferente? _: Sí. Y esto es muy importante. – Nivas

+1

Ok, gracias por esa aclaración. Todavía deja abierta la pregunta: ¿qué pasa con las funciones realmente idénticas, como 'isEmpty' o' size'? ¿Por qué esos son redeclarados? – Albert