22 votes

Java : Différences entre l'interface Set et l'interface Collection

Je viens de regarder les Set et nous avons constaté qu'elle ne redéclarait que les fonctions déjà présentes dans l'interface Collection interface. Set s'étend lui-même Collection alors cela ne veut-il pas dire que le Set possède automatiquement toutes les fonctions de l'interface Collection ? Pourquoi sont-ils redéclarés alors ?

Par exemple, Set redéclare ceci :

/**
 * 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();

Et la déclaration dans 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();

Cela me semble très redondant. Pourquoi ne pas simplement définir le Set comme interface :

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

Je pense qu'il n'y a pas de différence unique entre ces interfaces, n'est-ce pas ?


Bien sûr, je ne pose pas de question sur les différentes sémantiques / significations des termes suivants Set . Je le sais. Je demande simplement si, techniquement (c'est-à-dire pour le compilateur), cela fait une différence. C'est-à-dire, d'une manière générale :

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

Maintenant, y a-t-il une différence entre A , B o C ?


Alors que le contrat (c'est-à-dire ce qui est dit dans la documentation) peut vraiment être différent pour certaines fonctions (comme pour les fonctions add ), il y a une raison valable de les redéclarer : Pour pouvoir mettre une nouvelle documentation, c'est à dire définir le nouveau contrat.

Cependant, il existe également des fonctions (comme isEmpty ) qui ont exactement la même documentation / le même contrat. Pourquoi sont-ils également redéclarés ?

14voto

Nick Fortescue Points 18829

Techniquement, pour le compilateur, cela ne fait aucune différence.

Cependant, un ensemble ne peut pas avoir d'entrées en double alors qu'une collection le peut. Cela vaut la peine de le savoir.

Pour cette raison, la sémantique des méthodes pour les paramètres, les valeurs de retour et ce qui se passe peut signifier différentes choses. La redéclaration permet également à la javadoc de devenir plus spécifique. Par exemple pour add() :

Set : @renvoie vrai si cet ensemble ne contenait pas déjà l'élément spécifié

Collection : @renvoyer vrai si cette collection a été modifiée à la suite de l'appel

Le sens de set est plus spécifique.

Même pour les méthodes qui ne sont pas plus spécifiques, cela permet à la javadoc d'être plus agréable. Par exemple, pour size() : "Renvoie le nombre d'éléments de cet ensemble (sa cardinalité)", ce qui est plus proche du langage que comprendront les personnes habituées aux ensembles mathématiques.

Les documents de l'API résument cela en disant : " L'interface Set place des stipulations supplémentaires, au-delà de celles héritées de l'interface Collection, sur les contrats de tous les constructeurs et sur les contrats des méthodes add, equals et hashCode. Les déclarations d'autres méthodes héritées sont également incluses ici par commodité. (Les spécifications accompagnant ces déclarations ont été adaptées à l'interface Set, mais elles ne contiennent pas de stipulations supplémentaires)."

9voto

hvgotcodes Points 55375

La réponse se trouve dans l'API java6 pour set.

" L'interface Set impose des stipulations supplémentaires, au-delà de celles héritées de l'interface Collection, sur les contrats de tous les constructeurs et sur les contrats des méthodes add, equals et hashCode. Les déclarations d'autres méthodes héritées sont également incluses ici par commodité. (Les spécifications accompagnant ces déclarations ont été adaptées à l'interface Set, mais elles ne contiennent pas de stipulations supplémentaires)."

6voto

Andy Thomas Points 30979

Une méthode ne se résume pas à sa signature.

Dans ce cas, la documentation de ces méthodes a été adaptée aux ensembles, en termes de conditions préalables et postérieures, et de terminologie.

2voto

Nivas Points 10159

Ils sont redéclarés car, même si les noms sont identiques, ils ont une signification différente. Le site add dans le Set es un spécifique l'implémentation du générique add méthode dans Collection .

L'intention est de spécifier explicitement que le add la méthode os le Set est très différente de la méthode d'ajout de Collection .

Pourquoi ne pas simplement définir l'interface Set comme :

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

Si cela a été fait de cette façon, il n'y aurait aucun endroit où le contrat de un Set peuvent être spécifiés. Comment puis-je savoir qu'en mettant en œuvre le add de la méthode Set Je ne dois pas autoriser les doublons ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X