2014-02-03 2 views
0

Может ли кто-нибудь объяснить мне, почему это запрещено на Java? У меня есть эти три файла (разделенные и упрощенные для StackExchange):Тип стирания предотвращает перегрузку, но позволяет переопределять

Суперкласс в моем случае для общих графиков. Параметр type указывает, как представлены дуги: либо с определенным классом дуги, либо с помощью целых чисел, указывающих уникальные идентификаторы.

public interface Base<A> { 
    public boolean removeArc(A arc); 
} 

Подкласс, имеющий конкретную реализацию для дуги.

public interface Sub<B> extends Base<Arc<B>> { 
    @Override 
    public boolean removeArc(Arc<B> arc); 

    public Arc<B> removeArc(B value); //Removes an arc with this specific value. 
} 

Реализация дуги.

public interface Arc<B> { 
} 

Netbeans дает мне следующие ошибки времени компиляции в Sub. В @Override:

name clash: removeArc(Arc<B>) in Sub overrides a method whose erasure is the same as another method, yet neither overrides the other 
    first method: removeArc(B) in Sub 
    second method: removeArc(A) in Base 
    where B,A are type-variables: 
    B extends Object declared in interface Sub 
    A extends Object declared in interface Base 

На втором методе:

name clash: removeArc(B) in Sub and removeArc(A) in Base have the same erasure, yet neither overrides the other 
    where B,A are type-variables: 
    B extends Object declared in interface Sub 
    A extends Object declared in interface Base 

Проблема, кажется, что removeArc(Arc<B>) и removeArc(B) имеют один и тот же стиранию, но я не вижу, почему это происходит. Удаление removeArc(Arc<B>) компилируется в порядке, без предупреждения о @Override, поэтому он должен понимать, что Arc<B> равно A в Base.

Почему Java не может отличить Arc<B> и B в этом случае?

+1

Это может быть ошибка в netbeans. Eclipse вообще не жалуется на этот код, поэтому проблема не присуща Java. Обычно я старался избегать перегрузок. –

+0

Aw, bugger если есть. Я посмотрю, смогу ли я найти, если это известная ошибка в Netbeans ... Спасибо. – Ghostkeeper

+0

Кажется, что все-таки присуще Java. Я не знаю, почему Eclipse не жалуется, но javac дает мне ту же ошибку. – Ghostkeeper

ответ

3

Компилятор удаляет общие классы во время компиляции. Он заменит владельца места его ограниченным классом.

В этом случае Base заменит любой экземпляр A с Object и Sub заменит любой экземпляр B с Object.

это дает конфликтующих Методы

в Базе public boolean removeArc(Object arc);

и в Суб public Arc removeArc(Object value);

однако если вы сделали

public interface Base<A extends Arc<?>> { 
    public boolean removeArc(A arc); 
} 

тогда экземпляры A будут заменены Arc и сигнатуры метода больше не будут конфликтовать.

+0

Выполняя это самостоятельно, я получаю «Base» с одним методом 'removeArc (Object)' и 'Sub', имеющим два метода:' removeArc (Object) 'и' removeArc (Arc) ', где' Sub # removeArc (Arc) 'переопределяет' Base # removeArc (Object) '. Я думаю об этом неправильно? Я не могу прибегнуть к вашему предложению, так как он побеждает цель иметь общий аргумент: иметь возможность обрабатывать явные «дуги», а также определять дуги по их уникальному идентификатору. – Ghostkeeper

+0

Вы делаете это правильно. Java имеет проблему с типами возврата. Изменил мой ответ. – BevynQ

+0

И все же, включая типы возвращаемых данных, я заканчиваю «Base» одним методом «boolean removeArc (Object)» и «Sub», имеющим два метода: «Arc removeArc (Object)» и «boolean removeArc (Arc)». Я бы ожидал, что 'Base # removeArc (Object)' и 'Sub # removeArc (Object)' не будут сталкиваться, поскольку 'Base # removeArc (Object)' больше не присутствует, так как он переопределен. – Ghostkeeper

Смежные вопросы