81 votes

Pourquoi faut-il privilégier l'interface d'une classe Java ?

PMD signalerait une violation pour :

ArrayList<Object> list = new ArrayList<Object>();

La violation était la suivante : "Évitez d'utiliser des types d'implémentation comme 'ArrayList' ; utilisez plutôt l'interface".

La ligne suivante corrigerait la violation :

List<Object> list = new ArrayList<Object>();

Pourquoi ce dernier avec List être utilisé à la place de ArrayList ?

0 votes

86voto

kolrie Points 3496

L'utilisation d'interfaces plutôt que de types concrets est la clé d'une bonne encapsulation et d'un couplage lâche de votre code.

C'est même une bonne idée de suivre cette pratique lorsque vous écrivez vos propres API. Si vous le faites, vous constaterez plus tard qu'il est plus facile d'ajouter des tests unitaires à votre code (en utilisant des techniques de simulacre) et de modifier l'implémentation sous-jacente si nécessaire à l'avenir.

Voici un bon article sur le sujet.

J'espère que cela vous aidera !

2 votes

Et pourquoi ne pas utiliser "Collection" au lieu de "Liste", afin d'aller un peu plus loin dans l'abstraction... ?

33voto

AdamC Points 5828

Cette solution est préférable car elle permet de découpler votre code de l'implémentation de la liste. L'utilisation de l'interface vous permet de changer facilement l'implémentation, ArrayList dans ce cas, pour une autre implémentation de liste sans changer le reste du code tant qu'il utilise uniquement les méthodes définies dans List.

12voto

Owen Points 1030

En général, je suis d'accord pour dire que découpler l'interface de l'implémentation est une bonne chose et rendra votre code plus facile à maintenir.

Il existe toutefois des exceptions dont vous devez tenir compte. L'accès aux objets par le biais d'interfaces ajoute une couche supplémentaire d'indirection qui rendra votre code plus lent.

Par curiosité, j'ai réalisé une expérience qui a généré dix milliards d'accès séquentiels à une liste de tableaux d'un million de caractères. Sur mon MacBook 2.4Ghz, l'accès à la liste de tableaux par l'intermédiaire de l'interface List a pris 2,10 secondes en moyenne, alors qu'en la déclarant de type ArrayList, cela a pris en moyenne 1,67 seconde.

Si vous travaillez avec de grandes listes, au cœur d'une boucle interne ou d'une fonction fréquemment appelée, il faut en tenir compte.

0 votes

@Owen : +5 Perspicace concernant la différence de performance ... Très inattendu

2 votes

Cette réponse montre toutefois que les frais généraux peuvent être très faibles : stackoverflow.com/questions/890687/

6 votes

Wow ! 0,5 seconde pour dix milliards d'accès, c'est-à-dire qu'un accès à une interface est plus lent d'une demi-nanoseconde qu'un accès à une classe ! C'est bien sûr une raison pour ne jamais, au grand jamais, utiliser les interfaces.

6voto

SCdF Points 11397

ArrayList et LinkedList sont deux implémentations d'une liste, qui est une collection ordonnée d'éléments. D'un point de vue logique, le fait d'utiliser une ArrayList ou une LinkedList n'a pas d'importance, vous ne devriez donc pas imposer ce type.

Cela contraste avec, disons, Collection et Liste, qui sont des choses différentes (la Liste implique un tri, la Collection non).

1voto

MetroidFan2002 Points 11413

Les propriétés de vos classes/interfaces doivent être exposées par le biais d'interfaces car cela donne à vos classes un contrat de comportement à utiliser, quelle que soit l'implémentation.

Cependant...

Dans les déclarations de variables locales, cela n'a guère de sens :

public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}

S'il s'agit d'une variable locale, utilisez simplement le type. Elle est toujours implicitement upcastable vers son interface appropriée, et vos méthodes devraient, si tout va bien, accepter les types d'interface pour leurs arguments, mais pour les variables locales, il est tout à fait logique d'utiliser le type d'implémentation comme conteneur, juste au cas où vous auriez besoin de la fonctionnalité spécifique à l'implémentation.

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