2010-11-16 24 views
0

J'ai une classe qui étend le tableau ArrayList de Java. J'utilise actuellement Java build 1.6.0_22-b04. Ressemble à ceci:Problème lors de la substitution de la méthode ArrayList add

public class TokenSequence extends ArrayList<Token>{ 
    public TokenSequence (Collection<Token> tokens) { 
     super(tokens); 
    } 

    public void add(Object o) { 
     if (o instanceof Token){ 
      add((Token)o); 
    } 
    else if (o instanceof TokenSequence) 
     add((TokenSequence)o); 
    else 
     add(new Token(o.toString())); 
    } 

} 

Mon problème dans le code ci-dessus est la méthode add (Object o). Java ne me laisse pas compiler le code, car il dit

"Name clash: The method add(Object) of type TokenSequence has the same erasure as add(E) of type ArrayList<E> but does not override it" 

Ce même code fonctionne sans problème dans un autre ordinateur sous Java 1.6.0_17-b04 construire.

Quelqu'un a une idée sur une solution rapide?

+0

Êtes-vous sûr que votre code ne compile pas? –

+0

@org: Il a probablement mis les avertissements en erreur. – SLaks

+0

@SLaks standard javac ne prévient même pas –

Répondre

2

Changez-le en public boolean add(Token o). (Note return et type de paramètre)

Pour remplacer une méthode, votre remplacement doit avoir exactement la même signature, y compris le type de retour.
Étant donné que votre méthode a un type de retour différent, elle ne remplace pas la méthode de base add.

La raison pour laquelle il ne sera même pas compilé est que parce qu'il ne remplace pas la méthode de base, vous finissez avec deux méthodes add différentes, qui sont appelables par votre classe dérivée.
Toutefois, en raison de l'effacement du type, ils prennent tous les deux un paramètre Object, ce qui est illégal.

+1

le code de OP devrait compiler. –

0

que vous devez faire:

public boolean add(Token o) { 
    } 

Parce que ArrayList est un générique.

1

Absolument - utiliser l'annotation @Override, et utiliser idéalement la signature fortement typé:

@Override 
public void add(Token token) { 
    ... 
} 
+5

le type de retour doit être 'booléen' –

0

Le message d'erreur déjà fourni un grand indice ici.

Je ne l'ai pas essayé, mais je crois que la mise en œuvre correcte serait:

public void add(Token o) { 
} 

parce Token est le E dans votre instruction extends.

4

Essayez d'ajouter la méthode annotation @Override à votre add() et assurez-vous d'avoir la même signature (type de retour booléen)

public class TokenSequence extends ArrayList<Object> { 
    @Override 
    public boolean add(Object e) { 
    return super.add(e); 
    } 
} 

Ou si vous voulez qu'il soit vide, prendre une autre méthode param.

acclamations

0

Tout d'abord, dans la mise en œuvre actuelle, il ira à une récursion infinie lorsque vous essayez d'appeler la fonction ajouter avec instance de TokenSequence. Vouliez-vous appeler "addAll" dans ce cas?

En second lieu, oublier

void add(Object) 

en cas vous devez ajouter 2 méthodes (faire revenir booléen, si vous voulez être cohérent):

public void add(String o) { 
    add(new Token(o.toString())); 
} 

public void add(TokenSequence t){ 
    addAll(t); 
} 

et le module complémentaire (Token d'autre part, si vous voulez une seule méthode, vous pouvez déclarer, par exemple:

public void add(Serializable t) 

cette méthode sera appelée pour TokenSequence et String. malheureusement faire la même méthode exécutée pour Token (en opposition à celui fourni par ArrayList), vous aurez besoin:

  1. assurez-vous que Token implémente Serializable
  2. cast jeton à SERIALIZABLE

-à-dire :

add((Serializable)new Token())