0

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?

Matteo
  • 539
  • 3
  • 9
  • 1
    Overload resolution is going via the variable type, not the actual type behind it. You need to do `instanceof` and then cast. You can not do this dynamically since the route has to be carved in stone at compile-time. It would probably be better to just have one method and have an `instanceof` switch in it. – Zabuzard Jul 24 '21 at 20:18
  • 1
    If such a dynamic cast would be allowed, you could easily create a program that compiles although it shouldnt compile. For example suppose you only created a method overload for `Dog` and `Cat`, when you get an arbitrary `Animal`. Now, after you compiled this code, you add a `Fish` to the inheritance tree. Which method should the fish go? There is no matching overload. Should it fail on runtime only? Such a feature is kinda going against Javas design goals. – Zabuzard Jul 24 '21 at 20:22
  • create an method called `talk()` in `Animal` and override in subtypes, better still use composition and strategy pattern and provide a "talk" strategy. Currently you lower bound for your list will always be `Animal`. – Mark Jul 24 '21 at 20:25

0 Answers0