是否可以使用类型参数 List<Animal> 使用 List 覆盖继承的方法<Dog>?



我在更改继承方法的类型参数时遇到问题。

abstract class Animal {
abstract List<Animal> animalList();
}
public class Dog extends Animal {
@Override
public List<Dog> animalList() {
...
...
}
}
public class Cat extends Animal {
@Override
public List<Cat> animalList() {
...
...
}
}

所有动物子类都需要实现一个方法animalList。如果我想要关于可读性和可维护性的最佳代码,那么这样做的最佳实践是什么?请注意,与实际项目相比,这是极其简化的。

我不知道什么是最好的解决方案,但我会做以下事情:

import java.util.List;
abstract class Animal {
abstract <T extends Animal> List<T> animalList();
}

import java.util.List;
public class Dog extends Animal {
@Override
List<Dog> animalList() {
return null;
}
}

import java.util.List;
public class Cat extends Animal{
@Override
List<Cat> animalList() {
return null;
}
}

虽然已经提供了有效的解决方案,但我将提供一些有用的参考资料。

为什么你不能"将狗或猫归为动物";它们被封装在集合中(在本例中为java.util.List(。

F.e.你可以这样写:

abstract class Animal {
abstract Animal[] animalArray();
}
public class Dog extends Animal {
@Override
public Dog[] animalArray() {
//
}
}
public class Cat extends Animal {
@Override
public Cat[] animalArray() {
//
}
}

为什么不能对List执行同样的操作?

因为在Java中,数组是协变的,但泛型类型(Collection<E>(是不变的。

在我读过的最好的Java书中,对这个主题有一个很好的解释——";有效Java";(现在有第三版(,作者J.Bloch(第28项:首选列表而非数组(。

良好的工作解决方案由@Zymus提供,使用所谓的">递归类型绑定";,这在书中也有描述(第30项:支持泛型方法(。

感觉有点奇怪,但这可能会奏效。

abstract class Animal<T extends Animal<T>> {
abstract List<T> animalList();
}
class Dog extends Animal<Dog> {
@Override
List<Dog> animalList() {
}
}
class Cat extends Animal<Cat> {
@Override
List<Cat> animalList() {
}
}

相关内容

最新更新