我一直在尝试使用泛型和多态性。我遇到了一个无法解决的问题。
说我有
public abstract class Animal {
private age;
private weight;
public Animal(){}
public void Move(){
//stuff
}
public void Eat(){
//stuff
}
//Getters and setters
}
然后
public Cat extends Animal {
//Constructors
}
public Snake extends Animal {
//Constructors
public void ShedSkin(){
//stuff
}
}
我也有自己的类(class)“MyAbstractClass”。在这里,我似乎无法解决问题。
public abstract class MyAbstractClass {
private List<Animal> myAnimalList;
public MyAbstractClass(){}
public MyAbstractClass(List<? extends Animal> animalList) {
this.myAnimalList = animalList;
}
public List<Animal> getAnimalList() {
return myAnimalList;
}
//Stuff which DOES NOT add to the list
}
我希望能够做到:
public class MyCatClass extends MyAbstractClass {
public MyCatClass(List<Cat> catList) {
super(catList);
}
}
public class MySnakeClass extends MyAbstractClass {
public MySnakeClass(List<Snake> snakeList) {
super(snakeList);
}
public ShedSkin(){
(Snake)getAnimalList().get(0).ShedSkin(); //Dont worry about indexing
}
}
然后
public static void main(string[] args) {
//Make list of cats
//Make list of snakes
MyCatClass cats = new MyCatClass(catList);
MySnakeClass snakes = new MySnakeClass(snakeList);
snakes.ShedSkin();
}
这对我不起作用。在 public MyAbstractClass(List<? extends Animal> animalList)
编译失败.这有点超过我的 Java 经验,非常感谢一些指导。我希望示例类足够清楚以理解我的意图。
编译器告诉我:java.util.List<Animal> in MyAbstractClass cannot be applied to java.util.List<capture<? extends Animal>>
谢谢。
编辑: 看来我必须说明我要做什么。我有一个动物列表,它们可能有也可能没有比父类(super class)更多的字段和方法,但它们都扩展了父类(super class)。 我还想要一个接受单一类型动物列表的类,并在列表中的每个元素上或之上调用方法。我不会在列表中添加任何内容,所以这应该不是问题。 我之所以这样分开是因为所有动物之间,有很多相似之处,但有些动物有特殊性。接受 List 的类需要能够处理这些特殊性。因此,让工作类扩展一个父类(super class)并实现额外的方法。
编辑2: 解决了!
public abstract class MyAbstractClass {
private List<? extends Animal> myAnimalList;
public MyAbstractClass(){}
public MyAbstractClass(List<? extends Animal> animalList) {
this.myAnimalList = animalList;
}
public List<Animal> getAnimalList() {
return myAnimalList;
}
//Stuff which DOES NOT add to the list
}
字段和构造函数都需要是List<? extends Animal> foobar
.
建设性的头脑 Storm session !
编辑3: Dima的方法更好。
最佳答案
嗯,你不能分配 List<? extends Animal>
到 List<Animal>
,因为列表不是协变的:前者不是后者的子类。
您需要将基类成员的声明(以及 getAnimalList()
的返回类型)更改为 List<? extends Animal>
.您在其中一条评论中提到,这样做会给您带来 MyCatClass
中的某种其他错误。 ,但你一定是弄错了,如果基类中的所有内容都正确声明(不是 List<Animal>
,而是 List<? extends Animal>
),那么该类应该没问题。
这一行:(Snake)getAnimalList().get(0).ShedSkin()
可能是那个给你带来麻烦的人。首先,您需要在蛇周围加上一对括号:((Snake) getAnimalList().get(0)).ShedSkin()
,其次,你不能投 List<Animal>
至 List<Snake>
, 确保 getAnimalList()
声明返回 List<? extends Animal>
,那么一切都应该编译。
我认为,在您的情况下,更好的选择是对基类进行参数化:
public abstract class MyAbstractClass<T extends Animal> {
private List<T> myAnimalList;
public MyAbstractClass(List<T> animals) { myAnimalList = animals; }
public List<T> getAnimalList() { return myAnimalList; }
//etc.
}
public class MyCatClass extends MyAbstractClass<Cat> {
public MyCatClass(List<Cat> cats) { super(cats); }
}
public class MySnakeClass extends MyAbstractClass<Snake> {
public MySnakeClass(List<Snake> snakes) { super(snakes); }
public ShedSkin() { getAnimalList().get(0).ShedSkin(); }
}
等 这样你就不需要求助于任何地方,因为列表的类型总是准确的。
关于Java - 通过构造函数将泛型列表传递给类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27631374/