As for the first question;
Overriding resolution is done at runtime, but overloading resolution is done at compile time.
Since the signature of your methods are not identical (different parameter types. It doesn't matter that one's the subclass of another), they're overloading.
Since resolved at compile time, the compiler does not know what the instance type is; only the declared type.
To the compiler, s.isClawedBy(t)
is the method isClawedBy(Kitten)
of the declared type Cat
.
The compiler says "yep, Cat can accept a Kitten in its method, that's what this method is".
So, at runtime, which method that will call has ALREADY been chosen by the compiler. The lookup is NOT performed at runtime.
Thus, at runtime, despite s
actually being a Kitten object, the Cat method is called.