random2 random2 - 1 month ago 8
Java Question

java generics and program-design, how to properly implement a list which contains subtypes of superclass?

I have an animal class and some actual animals like mouse, horse ... which are expending the class animal. Now I want to create a class population. A population has a list containing only one kind of animal.

I can run this approach, but it is rather ugly. With wildcards

<? extends Animal>
I don't need any casts, but adding another animal won't work. When I just use
<Animal>
, I always have to cast and I would have to write methods for every kind of animal for example
add_mouse()
, altough all of these methods would do nearly the same.

My first thougt was to introduce a population class for every kind of animal, but that wouldn't be a good solution either.

I kindly ask you for help. Is there a proper way it can be done or could you suggest me another program-design please?
Thank you very much.

Answer

You need an upper-bounded type variable on your Population class, and a List inside that class constrained to contain only instances of that type variable:

class Population<A extends Animal> {
  final List<A> animals = new ArrayList<>();

  void add(A animal) {
    animals.add(animal);
  }
}

Then you can use it some like this:

Population<Dog> dogs = new Population<>();
dogs.add(new Dog());  // OK.

Population<Cat> cats = new Population<>();
cats.add(new Cat());  // OK.

dogs.add(new Cat());  // Compiler error.
cats.add(new Dog());  // Compiler error.