我知道类型擦除,但这对我来说没有意义。
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)”与 'Base'中的'transform(Collection)';两种方法的擦除相同 却没有一个取代另一个
我的想法是我们可以覆盖transform
而不会出现编译器错误。
为什么transform
中的Derived
没有正确覆盖Base中的方法transform
?我知道这与类型擦除有关。我不明白为什么。
答案 0 :(得分:5)
该方法在基类中的签名:
<T> Collection<T> transform(Collection<T> list)
说:“我将接受具有 any 类型元素的集合,并向您返回相同类型的元素集合。
根据Liskov替换原理,实现此方法的任何子类都必须执行相同的操作。特别是,它必须接受具有任何类型元素的集合。
如果您尝试使用方法来覆盖它:
Collection<CharSequence> transform(Collection<CharSequence> list)
然后,它不执行所需的操作:它不接受任何类型的集合元素,仅接受特定类型的元素。因此,它不会覆盖超类方法
通常,在子类中定义不覆盖超类中的方法的方法没有问题:您可以在子类中定义超类中不存在的新方法。但是由于类型擦除,您无法继续使用这两种方法,因为它们具有相同的签名。因此,编译器不允许您这样做。
答案 1 :(得分:4)
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<>();
}
}