使用类型参数覆盖泛型方法时的编译错误

ham*_*uki 2 java generics overriding

我知道类型擦除,但这对我来说没有意义。

class Base{
   public <T> Collection<T> transform(Collection<T> list)
   { 
      return new ArrayList<T>(); 
   }
} 
Run Code Online (Sandbox Code Playgroud)

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

我的IDE中生成一个错误:

“派生”中的“ transform(Collection)”与“基本”中的“ transform(Collection)”冲突;两种方法具有相同的擦除,但是都不能覆盖另一种方法

我的想法是我们可以transform在编译器没有错误的情况下进行覆盖。为什么transformDerived中不能正确覆盖transformBase中的方法?我知道这与类型擦除有关。我不明白为什么。

Ole*_*hov 5

Base并且Derived不是通用类,并且Collection<T>in BaseCollection<CharSequence>in 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<>();
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,有效的替代将是:

class Derived extends Base {
    @Override
    public <T> Collection<T> transform(Collection<T> list) {
        return new HashSet<>();
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*ner 5

基类中方法的签名:

<T> Collection<T> transform(Collection<T> list)
Run Code Online (Sandbox Code Playgroud)

说:“我将接受具有任何类型元素的集合,并向您返回相同类型的元素的集合。

根据Liskov替换原理,实现此方法的任何子类都必须这样做。特别是,它必须接受具有任何类型元素的集合。

如果尝试使用方法覆盖此方法:

Collection<CharSequence> transform(Collection<CharSequence> list)
Run Code Online (Sandbox Code Playgroud)

则它不执行所需的操作:它不接受任何类型的collection元素,仅接受特定类型的元素。因此,它不会覆盖超类方法

通常,在子类中定义不覆盖超类中的方法的方法没有问题:您可以在子类中定义超类中不存在的新方法。但是由于类型擦除,您无法继续使用这两种方法,因为它们具有相同的签名。因此,编译器不允许您这样做。