Java 具有抽象类的构造函数-不接受特定

Java 具有抽象类的构造函数-不接受特定,java,Java,我有一个抽象类动物和扩展类马和猪。我还有一个Farm类和该类中的构造函数,我想用它来填充农场中动物的列表。但是编译器显示错误 我将列出Farm类,因为我认为这将说明问题,而无需列出全部内容: import java.util.ArrayList; public class Farm { public ArrayList<Animal> farmlist; { System.out.println("Initializing the farmlis

我有一个抽象类动物和扩展类马和猪。我还有一个Farm类和该类中的构造函数,我想用它来填充农场中动物的列表。但是编译器显示错误

我将列出Farm类,因为我认为这将说明问题,而无需列出全部内容:

import java.util.ArrayList;


public class Farm {
    public ArrayList<Animal> farmlist;
    { 
        System.out.println("Initializing the farmlist...");
        farmlist = new ArrayList<>();
        farmlist.add(new Horse()); // There will always be a Horse in the farm.
    }

    public Farm() {
        System.out.println("Blank constructor called..");

    }

    public Farm(Animal animal, int n) {
        System.out.println("Multiple animal constructor called...");
        for (int i = 1; i <= n; i++) {
            farmlist.add(new animal());
        }
    }
}
最后一行代码给出了一个编译器错误,它似乎不允许我传入Pig类型,例如,如果我想传入的话。这个想法是,它将把我传入的任何类型的多种动物添加到农场列表中。我不明白为什么它不让我这么做,或者我需要用什么方式来表达我正在努力做的事情

这个想法是,它将把我传入的任何类型的多种动物添加到农场列表中

在这种情况下,您需要传入动物的类型,而不是引用动物的实例,这是您目前正在做的事情。我怀疑你真的想要这样的东西:

public Farm(Class<? extends Animal> animalType, int n)
       throws ReflectiveOperationException {
    System.out.println("Multiple animal constructor called...");
    for (int i = 0; i < n; i++) {
        farmlist.add(animalType.newInstance());
    }
}
另一个最适合Java8+的选项是传入一个创建新动物的函数。例如:

public Farm(Supplier<? extends Animal> supplier, int n) {
    for (int i = 0; i < n; i++) {
        farmlist.add(supplier.get());
    }
}
请注意,如果您将kocko的答案与原始签名一起使用,您不会得到多个独立的动物对象,而是得到包含多个对同一动物对象的引用的列表。了解对象和引用在Java中的工作方式非常重要,最好从好书或教程中学习

这个想法是,它将把我传入的任何类型的多种动物添加到农场列表中

在这种情况下,您需要传入动物的类型,而不是引用动物的实例,这是您目前正在做的事情。我怀疑你真的想要这样的东西:

public Farm(Class<? extends Animal> animalType, int n)
       throws ReflectiveOperationException {
    System.out.println("Multiple animal constructor called...");
    for (int i = 0; i < n; i++) {
        farmlist.add(animalType.newInstance());
    }
}
另一个最适合Java8+的选项是传入一个创建新动物的函数。例如:

public Farm(Supplier<? extends Animal> supplier, int n) {
    for (int i = 0; i < n; i++) {
        farmlist.add(supplier.get());
    }
}

请注意,如果您将kocko的答案与原始签名一起使用,您不会得到多个独立的动物对象,而是得到包含多个对同一动物对象的引用的列表。了解对象和引用在Java中的工作方式非常重要,这可能是最好从好书或教程中学习的内容。

类名是Animal还是Animal?Java区分大小写。类名是Animal还是Animal?Java是区分大小写的,非常好,这就清楚了。如果我传入了一个对象,那么我将创建对同一对象的多个引用,这很愚蠢。谢谢乔恩:太好了,这就把事情弄清楚了。如果我传入了一个对象,那么我将创建对同一对象的多个引用,这很愚蠢。谢谢你,乔恩: