2010-09-26 11 views
1

J'ai appris récemment 3 nouvelles langues et je commence à les confondre. Je n'ai pas travaillé Java en faisant quelque chose de particulièrement complexe (en dehors d'Android) dans quelques années. Je n'arrive pas à me souvenir si cela est possible:Modification de la sémantique des méthodes de la sous-classe dans Java

Je sous-classe ArrayList principalement pour que je puisse garder l'arrayliste ordonné. J'essaye de surcharger la méthode add(object) mais je veux qu'elle renvoie un int au lieu d'un booléen (l'emplacement de l'objet qui a été ajouté). Mais je reçois des erreurs sur le type de retour de ma méthode.

Est ce que je veux même possible dans la langue? Pouvez-vous avoir une méthode dans une sous-classe de retour quelque chose de différent de la méthode de la superclasse? Ou est-ce que j'essaie de faire quelque chose de stupide? Est-ce que cela brise l'idée de l'héritage is-a? Devrais-je simplement encapsuler un arraylist au lieu de l'allonger?

Pour référence, une partie de ce que je suis en train de faire:


public class AuthorArray extends ArrayList \{ 

    @Override 
    public int add(Author object) { 
     super.add(object); 

     Collections.sort(this, new SortByLastName()); 

     return this.indexOf(object); 
    } 
} 
+1

Je pense que l'utilisation d'un 'ArrayList' pas idéale pour cela. Essayez un 'SortedSet', par exemple: un' TreeSet'. – NullUserException

Répondre

3

Pouvez-vous avoir une méthode dans une sous-classe retour quelque chose de différent que la superclasse méthode?

En général, non. La seule exception est les types de retour covariant, lorsqu'une méthode substituée renvoie une sous-classe du type de retour dans la méthode de classe/interface de base. Cela est devenu possible avec Java5, et c'est une bonne pratique. Mais votre cas ne tombe pas dans cette catégorie.

Est-ce que cela brise l'idée d'un héritage?

Oui. Les utilisateurs de ArrayList s'attendent à obtenir une valeur de retour boolean de add, et voir les éléments dans le même ordre où ils les ont ajoutés, et vous briser cette attente. Ne fais pas ça.

Devrais-je simplement encapsuler un arraylist au lieu de l'allonger?

Oui. Ensuite, vous pouvez définir votre propre interface, quel que soit le contrat que vous préférez. Mais d'abord, envisager d'utiliser un TreeSet à la place.

+0

Ah merci. Je ne pouvais pas pour la vie de moi trouver une classe de collections triées pour une raison quelconque. Je ne sais pas quel était mon problème – Falmarri

0

L'interface List garantit que les éléments seront retournés dans le même ordre que celui dans lequel ils ont été ajoutés. Ainsi, si vous n'avez qu'un thread manipulant la liste, vous pouvez facilement effectuer un ajout et ensuite demander sa taille. size - 1 est la valeur ordinale de l'élément.

Si l'ordre ci-dessus n'est pas ce que vous voulez, vous avez deux choix - soit trier la liste en utilisant les méthodes Collection.sort(), ou utiliser un SortedSet. Les deux méthodes peuvent prendre un comparateur.

Je n'ai jamais trouvé le besoin d'étendre le framework de collections Java et je ne vous recommande pas de le faire dans cette circonstance.

1

La modification de la sémantique est mauvaise. Dans votre cas, changer le nom de la méthode de add à myadd résoudrait votre problème, si vous voulez une solution simple.

Personnellement, je recommande d'apprendre à utiliser Google guava-libraries structures de données immuables, triées avec 'fonction', pour obtenir un aperçu de mise à jour, naviguez sur youtube.

Mais ici en Java standard, j'ai fait un exemple, comment utiliser TreeSet autosort - classe personnalisée, comparateur de valeur 2, et l'équivalent de recherche binaire efficace.

public static class customC { 
    private String name; 
    private int value; 

    public customC(String name, int value) {super();this.name = name;this.value = value;} 
    public String getName() {return name;} 
    public void setName(String name) {this.name = name;} 
    public int getValue() {return value;} 
    public void setValue(int value) {this.value = value;} 

    @Override 
    public String toString() { 
     return new StringBuilder().append("[").append(this.name) 
       .append(":").append(this.value).append("]").toString(); 
    } 
} 

public static void main(String[] args) { 
    TreeSet<customC> ts = new TreeSet<customC>(new Comparator<customC>(){ 
     public int compare(customC a, customC b) { 
      int result = a.getName().compareToIgnoreCase(b.getName()); 
      return (result != 0 ? result : a.getValue() - b.getValue()); 
     } 
    }); 
    ts.add(new customC("ab", 1988)); 
    ts.add(new customC("ab", 1979)); 
    ts.add(new customC("ba", 1988)); 
    ts.add(new customC("ab", 1984)); 
    ts.add(new customC("ab", 1980)); 
    customC ce = new customC("ab", 1983); 
    ts.add(ce); 

    StringBuilder sb = new StringBuilder(); 
    sb.append(ts.headSet(ce).last()).append(" comes before ") 
     .append(ce).append("\n").append(ts); 

    System.out.println(sb.toString()); 
} 

Affichera:

[ab:1980] comes before [ab:1983] 
[[ab:1979], [ab:1980], [ab:1983], [ab:1984], [ab:1988], [ba:1988]]