Java - 通过构造函数将泛型列表传递给类

标签 java generics inheritance polymorphism

我一直在尝试使用泛型和多态性。我遇到了一个无法解决的问题。

说我有

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/

相关文章:

Java java.util.logging.logger。使用数组对象作为参数

java - 如何在没有同步块(synchronized block)(即低成本锁)的情况下在一个安全操作中原子地检查 Java 中的两个 AtomicBooleans?

java - Lucene5.3.1中StandardFilter到底做了什么?

java - 如何定义通用排序类

C++ 从基类引用子类指针属性

python - 基本继承(在python中)

java - 如何获取Seekbar的值进行计算?

c# - 带有数组返回的泛型列表但是如何?

java - 编译器如何知道正在使用的类是泛型类,尽管它已被编译并且其类型已被删除为预泛型代码

ruby-on-rails - 单表继承路由?