Ошибка компиляции при переопределении универсального метода с параметром типа - PullRequest
2 голосов
/ 08 июня 2019

Мне известно о стирании типов, но для меня это не имеет смысла.

class Base{
   public <T> Collection<T> transform(Collection<T> list)
   { 
      return new ArrayList<T>(); 
   }
} 

И

public class Derived extends Base {
    @Override // compilation error
    public Collection<CharSequence> transform(Collection<CharSequence> list) {
        return new HashSet<CharSequence>();
    }
}

В моей среде IDE возникла ошибка:

'transform (Collection)' в 'Производные' конфликтует с 'transform (Collection)' в 'Base';оба метода имеют одно и то же стирание, но ни один из них не переопределяет другие

Я думал, что мы можем переопределить transform без ошибки компилятора.Почему transform в Derived неправильно корректирует метод transform в Base?Я знаю, это связано с стиранием типа , но.Я не могу понять, почему.

Ответы [ 2 ]

5 голосов
/ 08 июня 2019

Подпись метода в базовом классе:

<T> Collection<T> transform(Collection<T> list)

говорит: «Я приму коллекцию с элементами любого типа и верну вам коллекцию элементов этоготот же тип.

Согласно принципу подстановки Лискова, любой подкласс, который реализует этот метод, должен делать то же самое. В частности, он должен принимать коллекцию с элементами любого типа.

Если вы попытаетесьпереопределите это с помощью метода:

Collection<CharSequence> transform(Collection<CharSequence> list)

тогда он не будет делать то, что требуется: он не принимает элементы коллекции любого типа, он принимает только элементы определенного типаСледовательно, он не переопределяет метод суперкласса

Обычно нет проблем с определением метода в подклассе, который не переопределяет метод в суперклассе: вы можете определить новые методы в подклассе, которые нене существует в суперклассе. Но из-за стирания типов вы не можете продолжать иметь оба метода, поскольку они имеют одинаковую сигнатуру. Следовательно, компилятор запрещает вам fРом делает это.

4 голосов
/ 08 июня 2019

Base и Derived не являются общими классами, а Collection<T> в Base не имеет ничего общего с Collection<CharSequence> в Derived - между ними нет связи - отсюда ошибка!

Вы можете исправить это следующим образом:

class Base<T> {
    public Collection<T> transform(Collection<T> list) {
        return new ArrayList<>();
    }
}

class Derived extends Base<CharSequence> {
    @Override
    public Collection<CharSequence> transform(Collection<CharSequence> list) {
        return new HashSet<>();
    }
}

В противном случае допустимое переопределение будет:

class Derived extends Base {
    @Override
    public <T> Collection<T> transform(Collection<T> list) {
        return new HashSet<>();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...