In code below
public class Animal {
public void eat() {
System.out.println("Animal eating");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat eating");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("Dog eating");
}
}
public class AnimalFeeder {
public void feed(List<Animal> animals) {
animals.add(new Cat());
animals.forEach(animal -> {
animal.eat();
});
}
public static void main(String args[]){
List<Animal> a = new ArrayList<Animal>();
a.add(new Cat());
a.add(new Dog());
new AnimalFeeder().feed(a);
/* List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
dogs.add(new Dog());
new AnimalFeeder().feed(dogs); // not allowed
*/
}
}
I understand that feed(List<Animal> animals)
method cannot be passed a List<Dog>, List<Cat>
etc. If List<Dog>
were allowed, then animals.add(new Cat());
can be added too which is not desirable and because of type erasure at runtime.
So only List<Animal>
is allowed.
However, I can do the following
List<Animal> a = new ArrayList<Animal>();
a.add(new Cat());
a.add(new Dog());
and still call new AnimalFeeder().feed(a);
and when I run the program, it gives me
Cat eating
Dog eating
Cat eating
My understanding of polymorphic generic concept is that "we want our List<Animal>
to accept only List<Animal>
and also that that List contain only Animals, not Cat or Dog, in other words only Animals". Any other inclusion of dog or Cat is not wanted? Is that right? If yes, why am I allowed to pass List<Animal>
that contain dogs, cats etc. Is this not same thing as passing (assuming it is allowed) List<Dog>
and then adding new Cat()
to dog list?
I hope my question is clear.
I did go through Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
but I could find the answer to my question?
thanks,