If I have multiple implementations of a method, one of which takes an instance of a particular class, the other a superclass of it, how can I force the most specific one to be called?
Let us take the following code:
public static class Cat {};
public static class DomesticCat extends Cat {};
public static class Lion extends Cat {};
public static class CatOwner {
    public Cat cat;
}
public static void identifyCat(Cat cat) {
    System.out.println("Generic cat");
}
public static void identifyCat(Lion lion) {
    System.out.println("Lion");
}
Now if I do:
identifyCat(new Cat());
identifyCat(new Lion());
identifyCat(new DomesticCat());
I get:
Generic cat
Lion
Generic cat
So far, so good, Java picks the most specific one—except that matching is done based on the declared class (or whatever I cast it to), not the actual one. For example, the following code:
Cat simba = new Lion();
identifyCat(simba);
calls identifyCat(Cat), not identifyCat(Lion)—because simba is declared as Cat.
For a more realistic use case, let us assume that Cat and all its subclasses are defined in an external library (which I have no control over), and I get a Cat instance from there with no control over the actual class of the instance, like:
Cat cat = CatFactory.getCat();
identifyCat(cat);
This will always call identifyCat(Cat), even if the Cat instance returned is of type Lion.
Considering I might have more implementations for identifyCat(), and they do more than just identify the instance (they might, for instance, interact with members introduced by that particular subclass): is there an easy way to get my code to call identifyCat(Lion) for a Lion (even if declared as Cat), without resorting to enumerative if statements à la if (cat instanceof Lion) identifyCat((Lion) cat)?