2010-11-16 5 views
0

У меня есть класс, расширяющий Java ArrayList. В настоящее время я использую Java build 1.6.0_22-b04. Нам кажется, это так:Проблема переопределения метода добавления ArrayList

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())); 
    } 

} 

Моя проблема в приведенном выше коде является метод add (Object o). Java не позволит мне скомпилировать код, потому что он говорит

"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" 

Этот же код работает без проблем на другом компьютере под Java 1.6.0_17 строить-B04.

У кого-нибудь есть идеи по быстрому исправлению?

+0

Вы уверены, что код не компилируется? –

+0

@org: Вероятно, он установил предупреждения как ошибки. – SLaks

+0

@SLaks стандарт javac даже не предупреждает –

ответ

2

Изменить его на public boolean add(Token o). (Примечание return и тип параметра)

Чтобы переопределить метод, ваше переопределение должно иметь ту же самую подпись, включая тип возврата.
Поскольку ваш метод имеет другой тип возвращаемого значения, он фактически не переопределяет базовый метод add.

Причина, по которой он даже не компилируется, заключается в том, что, поскольку он не переопределяет базовый метод, вы получаете два разных метода add, оба из которых могут быть вызваны вашим производным классом.
Однако из-за стирания типа они оба принимают параметр Object, что является незаконным.

+1

код OP должен компилироваться. –

0

Вам нужно сделать:

public boolean add(Token o) { 
    } 

Поскольку ArrayList является общим.

1

Абсолютно - использовать @Override аннотации, а в идеале использовать сильно типизированную подпись:

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

Тип возврата должен быть 'boolean' –

0

сообщения об ошибке уже при условии большого намека здесь.

Я не пробовал, но я считаю, что правильная реализация будет:

public void add(Token o) { 
} 

потому Token в вашей распространяется заявление E.

4

метод Попробуйте добавить аннотацию @Override к надстройке() и убедитесь в том, чтобы иметь такую ​​же подпись (логический тип возвращаемого значения)

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

Или, если вы хотите его недействительным, сделать еще один метод параметров.

веселит

0

Прежде всего, в текущей реализации он будет идти к бесконечной рекурсии, когда вы пытаетесь вызвать добавить функцию с экземпляром TokenSequence. Вы хотели называть «addAll» в этом случае?

Во-вторых, забыть о

void add(Object) 

в вас случае вам нужно добавить 2 метода (сделать их возвращают логическое значение, если вы хотите, чтобы быть последовательным):

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

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

и надстройку (токен) уже реализована ArrayList

, с другой стороны, если вы хотите использовать один метод, вы можете заявить, например:

public void add(Serializable t) 

Этот метод будет вызван как для TokenSequence, так и для String. , к сожалению, сделать тот же метод, выполняемый для токена (как противостоять тому, предоставленной ArrayList), вам потребуется:

  1. убедитесь, что Токен реализует Serializable
  2. произнесения токен SERIALIZABLE

т.е. :

add((Serializable)new Token()) 
Смежные вопросы