[英]How to override generic list return type in java
我试图覆盖返回类型为子类中的列表的方法,如下例所示,由于泛型问题,我无法在子类中执行此操作。 我无法改变我的超类代码,所以我如何解决这个问题? 任何人都可以指导我...非常感谢提前。
无法更新的超级课程:
public class Animal {
private String legs;
}
public class TestSuper {
public List<Animal> addAnimals() {
return animals;
}
}
子类:
public class Dog extends Animal {
private String sound;
}
public class TestSub extends TestSuper {
public List<Dog> addAnimals() { --> I need to override this method but want return type as List of dogs
return null;
}
}
如果超级班真的无法更新,我恐怕你根本就不能。
如果您能够更新超类:
在TestSuper
,你会使用public List<? extends Animal> addAnimals()
public List<? extends Animal> addAnimals()
而不是public List<Animal> addAnimals()
。
你有什么其他解决方案:
您可以使用这样的实用方法:
@SuppressWarnings("unchecked")
public static <T extends Animal> List<T> cast(List<Animal> animals, Class<T> subclass) {
List<T> out = new ArrayList<T>();
for (Animal animal : animals) {
if (!subclass.isAssignableFrom(animal.getClass())) {
// the "animal" entry isn't an instance of "subclass"
// manage this case however you want ;)
} else {
out.add((T) animal);
}
}
return out;
}
然后,打电话:
List<Dog> dogs = TheClassNameYouChose.cast(animals, Dog.class);
您不能将List的泛型类型更改为该泛型类型的子类型。 问题是对任何实例的引用都可以是该实例的子类型。 让我们来看看这个例子
SuperType sup = new SubType();
sup.getAnimals().add(new Cat());
//adding cat is possible because getAnimals() returns List<Animal>
所以你要将Cat
添加到应该只包含Dogs
列表中,这是错误的。
同样在重写方法中,您不能将通用类型的列表更改为使用该泛型类型的超类型List<Dog>
(例如List<Dog>
to List<Animal>
)。 为什么? 让我们来看看这个例子
SuperType sup = new SubType();
Dog d = sup.getAnimals().get(0);
在子类型中我们有动物列表,因此get(0)
可能会返回Cat。
如果您可以更改类中的代码,那么可以试试这种方法
class Super<T extends Animal> {
public List<T> addAnimals() {
return null;
}
}
class Sub extends Super<Dog> {
@Override
public List<Dog> addAnimals() {
return null;
}
}
如果Dog
是Animal
的子类,你可能会这样做
以下签名:
public List<? extends Animal> addAnimals()
然后做
public List<Dog> addAnimals()
在子类中。
或者你可以使超类泛型<T>
和实现类<Dog>
您需要使TestSuper使用泛型来真正使其正常工作。
TestSuper<T extends Animal> {
public List<T> addAnimals() {
}
}
TestSub extends TestSuper<Dog> {
}
这是不可能的。 超级合同说如果你有:
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
以下代码必须有效:
TestSuper test = new AnySubclassOfTestSuper(); // including TestSub!
test.addAnimals().add(new Cat());
您在TestSub
类中的覆盖会违反该规则,因为您无法将Cat
添加到List<Dog>
。 由于它违反了面向对象类型系统的相当基本原则,因此您无法找到这种限制的完美解决方法。
建议更改超类使用List<? extends Animal>
List<? extends Animal>
将起作用,因为您无法向该列表添加任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.