L'extension de java ArrayList
Je voudrais étendre ArrayList pour ajouter un peu de méthodes pour une classe dont les instances seraient détenues par la prolongation de la liste de tableaux. Une illustration simplifiée exemple de code est ci-dessous.
Ce qui semble raisonnable pour moi, mais je suis très nouveau à Java et je vois d'autres questions qui découragent l'extension de ArrayList, par exemple L'extension de liste de tableaux et de Créer de nouvelles méthodes. Je ne sais pas assez de Java pour comprendre les objections.
Dans ma précédente tentative, j'ai terminer la création d'un certain nombre de méthodes dans ThingContainer qui ont été essentiellement pass-through pour liste de tableaux, de sorte que l'extension semblait plus facile.
Est-il une meilleure façon de faire ce que je suis en train de faire? Si oui, comment doit-il être mis en œuvre?
import java.util.*;
class Thing {
public String name;
public int amt;
public Thing(String name, int amt) {
this.name = name;
this.amt = amt;
}
public String toString() {
return String.format("%s: %d", name, amt);
}
public int getAmt() {
return amt;
}
}
class ThingContainer extends ArrayList<Thing> {
public void report() {
for(int i=0; i < size(); i++) {
System.out.println(get(i));
}
}
public int total() {
int tot = 0;
for(int i=0; i < size(); i++) {
tot += ((Thing)get(i)).getAmt();
}
return tot;
}
}
public class Tester {
public static void main(String[] args) {
ThingContainer blue = new ThingContainer();
Thing a = new Thing("A", 2);
Thing b = new Thing("B", 4);
blue.add(a);
blue.add(b);
blue.report();
System.out.println(blue.total());
for (Thing tc: blue) {
System.out.println(tc);
}
}
}
Personnellement, j'ai tendance à éviter de dériver les classes du JDK, car il pourrait être un changement dans la mise en œuvre que je ne contrôle pas, ou qui casse quelque chose dans mon poste que je n'étais pas au courant de--il y a parfois subtile "pièges" quand on s'appuie sur la superclasse comportement que l'on ne pense pas toujours à propos, ou pas penser si nous n'avons pas de détails de mise en œuvre.
ne serait-ce pas de problème s'applique également à l'aide de classes du JDK?
Tu veux dire simplement les utiliser sans sous-classement?
Oui. 9876543210
OriginalL'auteur foosion | 2011-11-11
Vous devez vous connecter pour publier un commentaire.
Rien dans sa réponse, décourage l'extension de ArrayList; il y avait un problème de syntaxe. Extension de classe existe, donc on peut ré-utiliser le code.
La normale objections à l'extension d'une classe est la "favoriser la composition au cours de l'héritage" discussion. L'Extension n'est pas toujours le mécanisme de prédilection, mais cela dépend de ce que vous faites réellement.
Les modifier, par exemple de composition comme demandé.
On n'aurait pas forcément besoin pour exposer une liste complète de l'interface, tout simplement la collection, ou rien du tout. Exposer aucune fonctionnalité réduit considérablement l'utilité générale, cependant.
En Groovy, vous pouvez simplement utiliser le
@Delegate
annotation pour construire les méthodes d'auto-magiquement. Java peut utiliser Projet De Lombok's@Delegate
annotation de faire la même chose. Je ne suis pas sûr de la façon de Lombok exposerait l'interface, ou si elle n'.Je suis avec glowcoder, je ne vois rien de fondamentalement mauvais dans l'extension dans ce cas, c'est vraiment une question dont la solution s'intègre mieux le problème.
Modifier pour plus de détails concernant la façon dont l'héritage peut violer l'encapsulation
Voir Bloch Effectif de Java, Point 16 pour plus de détails.
Si une sous-classe s'appuie sur la super-classe de comportement, et de la superclasse, les changements de comportement, la sous-classe peut se briser. Si nous n'avons pas le contrôle de la super-classe, cela peut être mauvais.
Voici un exemple concret, la levée du livre (désolé Josh!), en pseudo-code, et fortement paraphrasé (toutes les erreurs sont les miennes).
Puis nous l'utilisons:
Et il est de retour... trois? Nope. Six. Pourquoi?
HashSet.addAll()
est mis en œuvre surHashSet.add()
, mais c'est une mise en œuvre interne de détail. Notre sous-classeaddAll()
ajoute trois, les appelssuper.addAll()
, qui appelleadd()
, qui incrémente également compter.Nous pourrions supprimer la sous-classe de
addAll()
, mais maintenant nous sommes en s'appuyant sur la superclasse détails de mise en œuvre, ce qui pourrait changer. Nous pourrions modifier notreaddAll()
pour itérer et appeladd()
sur chaque élément, mais maintenant nous sommes de réimplanter superclasse comportement, ce qui est contraire au but, et ne peut pas toujours être possible, si la superclasse comportement dépend de l'accès aux membres privés.Ou une super-classe peut implémenter une nouvelle méthode que notre sous-classe ne veut pas dire un utilisateur de notre classe pourrait involontairement contourner comportement prévu par la possibilité d'appeler directement la méthode de la superclasse, de sorte que nous avons à suivre la super-classe de l'API pour déterminer quand, et si, la sous-classe doit changer.
java.util.List
de composer, si vous voulez toujours votre classe à la prolonger, vous devez faire un membreList
et puis, quel 20 autres méthodes standard? Donc oui, normalement, je suis d'accord que la composition est mieux que l'héritage. Mais je pense que dans ce cas, l'héritage est le chemin à parcourir.Je ne comprends pas comment j'allais mettre en œuvre la composition ici. Veuillez fournir des précisions. Ou vous dites que la normale objection ne s'applique pas ici?
Composite, vous devez créer l'application spécifique de la classe, de lui donner un
List
variable d'instance, et de déléguer sous forme de liste des fonctionnalités directement à la liste. Je vais mettre un petit exemple dans la réponse.aha. C'est en fait la façon dont j'ai commencé. Puis j'ai pensé extension serait mieux parce que je n'aurais pas besoin de mettre en œuvre ajouter, effacer, etc. des méthodes. L'Extension de me donner gratuitement.
OriginalL'auteur Dave Newton
Je ne pense pas que l'extension de arrayList est nécessaire.
Vous devriez juste envelopper ArrayList dans votre ThingContainer classe. ThingContainer peut alors avoir toutes les méthodes de traitement dont vous avez besoin. Pas besoin de s'étendre ArrayList; il suffit de garder un membre privé.
Espérons que cette aide.
Vous pouvez également envisager la création d'une interface qui représente votre Truc Classe. Cela vous donne plus de flexibilité pour l'extensibilité.
...
comment il va être possible d'ajouter
Thing
dansThingContainer
? 😛OriginalL'auteur b3bop
Voici ma suggestion:
Et
report()
n'est pas nécessaire en fait. toString() peut faire le reste.OriginalL'auteur Kowser