我已经阅读了所有信息,但仍然无法找到原因,在这个基本示例中,覆盖是不可能的。请解释一下。
class Fruit{}
class Apple extends Fruit{}
class Parent {
public Set<Fruit> getIt(){
return null;
}
}
class Child extends Parent {
@Override // THIS DOESN'T WORK
public Set<Apple> getIt(){
return null;
}
}
答案 0 :(得分:2)
重写方法的返回类型必须是重写方法的返回类型的子类型。 Apple
可能是Fruit
的子类型,但Java泛型在类型参数中是不变的,因此这并不意味着Set<Apple>
是Set<Fruit>
的子类型
否则你可以做以下事情:
Parent p = new Child();
Set<Fruit> fruitSet = p.getIt(); // actually a Set<Apple>
fruitSet.add(new Fruit()); // oops!
您可以使用类型边界来解决此问题:
class Parent {
public Set<? extends Fruit> getIt() {
return null;
}
}
class Child extends Parent {
@Override
public Set<Apple> getIt(){
return null;
}
}
答案 1 :(得分:2)
因为它没有超越。你想要的是协方差。这意味着您希望将子类Set<Apple>
的重写方法的返回类型Child
用作类Set<Fruit>
的原始方法Parent
的返回类型的子类型
但是,唉,Set<Apple>
不是Java中Set<Fruit>
的子类型,即使Apple
是Fruit
的子类型。原因很简单:如果Fruit
为Set<Fruit>
,您可以向Set<Apple>
添加任何Set<Fruit>
,然后您就可以添加Banana
a Set<Apple>
因为超类中的任何可能在子类中都是可能的......
因此Set<Fruit>
和Set<Apple>
是不相关的类型,这禁止覆盖。
答案 2 :(得分:0)
class Fruit{}
class Apple extends Fruit{}
class Parent {
public Set<? extends Fruit> getIt(){
return null;
}
}
class Child extends Parent {
@Override // THIS DOESN'T WORK
public Set<Apple> getIt(){
return null;
}
}
但是因为一个类不是它自己的子类,所以最好将水果子类化为另一个类(如SuperFruit)并在父getIt()
方法中使用它而不是Fruit