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

Compilation error when overriding a generic method with a type parameter

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

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)' in 'Derived' clashes with 'transform(Collection)' in 'Base'; both methods have the same erasure, yet neither overrides the other

我的想法是我们可以覆盖 transform 而不会出现编译器错误。 为什么 Derived 中的 transform 没有正确覆盖 Base 中的方法 transform?我知道它与 type erasure 有关但是。我不明白为什么。

BaseDerived 不是通用的 类 和 Base 中的 Collection<T> 与 [=13 中的 Collection<CharSequence> 无关=] - 它们之间没有联系 - 因此出错!

您可以按如下方式修复:

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

基类中方法的签名class:

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

说“我将接受包含 any 类型元素的集合,并且 return 你接受相同类型元素的集合。

根据 Liskov 替换原则,任何实现此方法的 subclass 都必须执行相同的操作。特别是,它必须接受包含任何类型元素的集合。

如果您尝试使用以下方法覆盖它:

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

那么它就不会执行所需的操作:它不接受任何类型的集合元素,它只接受 specific 类型的元素。因此它不会覆盖 superclass 方法

通常情况下,在subclass中定义一个方法没有问题,它不会覆盖superclass中的方法:您可以在sub[=28中定义新方法=] 在 superclass 中不存在。但是由于类型擦除,您不能继续使用这两种方法,因为它们具有相同的签名。因此,编译器不允许您这样做。