Beneficio di non sovraccaricare 'AbstractCollection.add ()' e di avere 'AbstractCollection.addAll ()'?

1

Esempio:

public class Something {
    private Set<String> names = new HashSet();

    public void add(String n) { names.add(n); }
    public void add(Set<String> set) { names.addAll(set); }
}

Ma sono curioso del perché AbstractCollection.add(E e) non sia sovraccaricato nello stesso modo in cui sovraccarico il mio Something.add(String n) . Perché c'è il AbstractCollection.addAll(Collection<? extends E> c) distinto?

Non posso immaginare che faccia alcuna differenza pratica.
Quindi, la mia conclusione è di sovraccaricare solo quando c'è una ragione strong, logica, per farlo. Sovraccaricare solo perché posso è scoraggiato?

    
posta konishiki 20.03.2016 - 01:04
fonte

2 risposte

3

Come sottolinea @MetaFight, add e addAll hanno semantica diversa. Ma c'è anche una prospettiva storica per il design dell'API Collection .

Il framework Collections è stato aggiunto a Java prima che supportasse i tipi generici. In quei giorni, l'API per la raccolta definiva i metodi come segue:

   boolean add(Object e)          // adds a single element

   boolean addAll(Collection c)   // adds all elements in the collection

Ora immagina che abbiano progettato l'API in questo modo:

   boolean add(Object e)          // adds a single element

   boolean add(Collection c)      // adds all elements in the collection

e qualcuno ha scritto questo:

   List list = new ArrayList();
   Object list2 = new ArrayList();
   List list3 = new ArrayList();
   list3.add(list);
   list3.add(list2);

Domanda: cosa dovrebbe ora list3? Risposta: una lista vuota.

Confusione ... non è vero? Ma questo illustra chiaramente il pericolo di avere sovraccarichi che fanno cose sostanzialmente diverse.

Ora da Java 5, dovresti (dovresti) dichiarare gli elenchi con tipi parametrizzati (non i tipi non elaborati) e l'esempio sopra (ipotetico) molto probabilmente ti darebbe errori di compilazione. Ma, ricorda, le collezioni sono state introdotte qualche anno prima dei tipi generici. Anche se volessero rinominare addAll come sovraccarico di add , non avrebbero potuto farlo senza rompere la compatibilità binaria.

I can't imagine it makes any practical difference.

Lo fa. Vedere l'esempio sopra ... per un'illustrazione del principio generale.

So, my conclusion is to only overload when there is strong, logical, reason to do so. Overloading just because I can is discouraged?

Sì, e sì. Ma anche, dovresti sovraccaricare quando i metodi essenzialmente la stessa cosa .

    
risposta data 20.03.2016 - 02:30
fonte
1

È perché add e addlAll hanno diversi significati .

add serve per aggiungere un singolo elemento alla raccolta.

addAll serve per aggiungere più elementi alla raccolta.

Poiché entrambi i metodi significano qualcosa di diverso, ha senso dare loro nomi distinti.

    
risposta data 20.03.2016 - 01:26
fonte

Leggi altre domande sui tag