Constructor with abstract class won't accept specific

I have an abstract class Animal with extended classes of Horse and Pig. I also have a Farm class and a constructor in that class which I want to use to populate a list of what Animals are in the Farm. But the compiler is showing errors.

I will list the Farm class as I think this will illustrate the problem without needing to list the whole thing:

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());
        }
    }
}

The last line of code gives a compiler error, it does not seem to allow me to pass in type Pig, for example, if I wanted to. The idea is that it will add multiple animals of whatever type I pass in to the farmlist. I cannot understand why it will not let me do this or what way I need to "phrase" what I am trying to do.

Jon Skeet
people
quotationmark

The idea is that it will add multiple animals of whatever type I pass in to the farmlist.

In that case you need to pass in the type of an Animal - not a reference to an instance of an Animal, which is what you're doing at the moment. I suspect you actually want something like:

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());
    }
}

That will try to call an accessible parameterless constructor on whatever type you pass in, n times. You'd call it like this:

Farm farm = new Farm(Pig.class, 10);

Another option (most suitable for Java 8+) would be to pass in a function which created a new animal. For example:

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

then call it with:

Farm farm = new Farm(() -> new Pig(), 10);

Note that if you use kocko's answer with your original signature, you don't end up with multiple independent animal objects - you end up with your list containing several references to the same animal object. It's very important to understand how objects and references work in Java - and it's probably something best learned from a good book or tutorial.

people

See more on this question at Stackoverflow