Suppose I have the following class hierarchy:
abstract class Animal {}
class Cat extends Animal {}
class Dog extends Animal {}
Consider the following code:
class Test {
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
Animal animal = cat;
talk(dog);
talk(cat);
talk(animal);
List<Animal> list = new ArrayList();
list.add(cat);
list.add(dog);
for(Animal animal : list)
talk(animal);
}
public static void talk(Animal animal) {
System.out.println("Animal");
}
public static void talk(Dog dog) {
System.out.println("Dog");
}
public static void talk(Cat cat) {
System.out.println("Cat");
}
}
When I run the program I get as output
Dog
Cat
Animal
Animal
Animal
This means that when referenced with an Animal reference, each Dog and Cat is seen just as an Animal of no specific kind. If I know the specific kind of the animal at compile time I can cast that animal to its specific kind and the desired talk method is dispatched; but if I am given a list of animal and I don't know at compile time the exact kind of each of them, how can I make the program invoke the specific talk method?