Polymorphisme: Pourquoi utiliser " List list = new ArrayList "au lieu de"ArrayList list = new ArrayList"? [dupliquer]

possibilité de duplication:

pourquoi préférer L'interface D'une classe Java?

Quand dois-je utiliser

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

ArrayList hérite de List , donc si certaines fonctionnalités de ArrayList ne sont pas dans List , alors j'aurai perdu certaines des caractéristiques de la ArrayList , à droite? Et le compilateur avis une erreur en essayant d'accéder à ces méthodes?

126
demandé sur Community 2012-03-24 19:18:01

8 réponses

la principale raison pour laquelle vous faites cela est de découpler votre code d'une implémentation spécifique de l'interface. Quand vous écrivez votre code comme ceci:

List list = new ArrayList();  

le reste de votre code sait seulement que les données sont de type List , ce qui est préférable car il vous permet de basculer entre différentes implémentations de l'interface List avec facilité.

par exemple, dire que vous écriviez une bibliothèque de tierce partie assez grande, et dites que vous avez décidé d'implémenter le noyau de votre bibliothèque avec un LinkedList . Si votre bibliothèque dépend fortement de l'accès aux éléments de ces listes, vous finirez par trouver que vous avez pris une mauvaise décision de conception; vous réaliserez que vous auriez dû utiliser un ArrayList (qui donne le temps D'accès O(1)) au lieu d'un LinkedList (qui donne le temps D'accès o(n)). En supposant que vous avez été la programmation d'une interface, un tel changement est facile. Vous changeriez simplement l'instance de List ,

List list = new LinkedList();

à

List list = new ArrayList();  

et vous savez que cela fonctionnera parce que vous avez écrit votre code pour suivre le contrat fourni par l'interface List .

d'autre part , si vous aviez implémenté le noyau de votre bibliothèque en utilisant LinkedList list = new LinkedList() , faire un tel changement ne serait pas aussi facile, car il n'y a aucune garantie que le reste de votre code n'utilise pas de méthodes spécifiques à la LinkedList de la classe.

en somme, le choix est une simple question de design... mais ce type de conception est très important (surtout lorsqu'on travaille sur de grands projets), car il vous permettra d'apporter des changements spécifiques à la mise en œuvre plus tard sans briser le code existant.

223
répondu Alex Lockwood 2016-04-21 21:22:15

cela s'appelle la programmation À l'interface. Cela sera utile au cas où vous souhaiteriez passer à une autre mise en œuvre de List à l'avenir. Si vous voulez quelques méthodes dans ArrayList alors vous devriez programmer à l'implémentation qui est ArrayList a = new ArrayList() .

63
répondu tsatiz 2012-06-21 22:30:19

cela est également utile lors de l'exposition d'une interface publique. Si vous avez une méthode comme celle-ci,

public ArrayList getList();

alors vous décidez de le changer en,

public LinkedList getList();

toute personne qui faisait ArrayList list = yourClass.getList() devra changer son code. D'autre part, si vous le faites,

public List getList();

changer l'implémentation ne change rien pour les utilisateurs de votre API.

19
répondu Brendan Long 2012-05-24 23:52:44

je pense que la réponse de @tsatiz est plutôt juste (programmation vers une interface plutôt qu'une implémentation). Cependant, en programmant sur l'interface vous ne perdrez aucune fonctionnalité . Laissez-moi vous expliquer.



Si vous déclarez votre variable comme une List<type> list = new ArrayList<type> vous ne perdez pas réellement n'importe quelle fonctionnalité de L'ArrayList. Tout ce que vous devez faire est de jeter votre list à un ArrayList . Voici un exemple:

List<String> list = new ArrayList<String>();
((ArrayList<String>) list).ensureCapacity(19);

en fin de compte, je pense que tsatiz a raison car une fois que vous lancez sur un ArrayList, vous ne codez plus sur une interface. Cependant, c'est toujours une bonne pratique de coder d'abord à une interface et, si cela devient plus tard nécessaire, de coder à une implémentation si vous le devez.

Espère que ça aide!

10
répondu SecondSun24 2012-03-27 18:52:58

cela vous permet d'écrire quelque chose comme:

void doSomething() {
    List<String>list = new ArrayList<String>();
    //do something
}

plus Tard, vous pouvez le modifier:

void doSomething() {
    List<String>list = new LinkedList<String>();
    //do something
}

sans devoir changer le reste de la méthode.

Cependant, si vous souhaitez utiliser un CopyOnWriteArrayList par exemple, vous devez le déclarer comme tel, et non comme une Liste de si vous vouliez utiliser ses méthodes supplémentaires (addIfAbsent par exemple):

void doSomething() {
    CopyOnWriteArrayList<String>list = new CopyOnWriteArrayList<String>();
    //do something, for example:
    list.addIfAbsent("abc");
}
7
répondu assylias 2012-03-28 08:15:34

j'utilise cette construction chaque fois que je ne veux pas ajouter de complexité au problème. C'est juste une Liste, pas besoin de dire quel genre de liste c'est, car ça n'a pas d'importance pour le problème. J'utilise souvent Collection pour la plupart de mes solutions, car à la fin, la plupart du temps, pour le reste du logiciel, ce qui importe vraiment, c'est le contenu qu'il contient, et je ne veux pas ajouter de nouveaux objets à la Collection.

d'Ailleurs, vous utilisez cette construction quand vous pensez que vous pouvez voulez modifier la mise en oeuvre de la liste que vous utilisez. Disons que vous utilisiez la construction avec un ArrayList, et que votre problème n'était pas sûr. Maintenant, vous voulez être thread-safe, et pour une partie de votre solution, vous changez d'utiliser un Vecteur, par exemple. Quant aux autres utilisations de cette liste, peu importe qu'il s'agisse d'un Araryliste ou D'un vecteur, juste une liste, aucune nouvelle modification ne sera nécessaire.

5
répondu SHiRKiT 2012-03-24 15:31:35

je suppose que le cœur de votre question est pourquoi program to an interface, not to an implementation

simplement parce qu'une interface vous donne plus d'abstraction, et rend le code plus flexible et résiliente aux changements, parce que vous pouvez utiliser différents implémentations de la même interface (dans ce cas, vous pouvez changer l'implémentation de votre liste en une liste de liens au lieu d'une liste de tableaux ) sans changer son client.

4
répondu Mouna Cheikhna 2014-09-04 11:47:53

en général, vous voulez programmer contre une interface. Cela vous permet d'échanger l'implémentation à tout moment. C'est très utile surtout quand vous passez une implémentation que vous ne connaissez pas.

cependant, il y a certaines situations où vous préférez utiliser la mise en œuvre concrète. Par exemple quand serialize dans GWT.

2
répondu stefan bachert 2012-03-24 16:07:51