I have searched through all the similar questions on late binding on stack overflow, and I would severely disagree with anyone who marks this question as a duplicate. First
Java uses late binding for all non-final, non-private instance methods. This is how polymorphism is implemented. All of the calls you commented on are determined at run time.
In
A a=new A();
a.foo();
a is referencing an A object so A's implementation will be found, bound and used.
In
B b=new B();
b.foo();
b is referencing a B object so B's implementation will be found, bound, and used.
In
ref=b;
ref.foo();
ref is referencing a B object so B's implementation will be found, bound, and used.
The static (declared) type of the variable is only used by the compiler to verify that such a method is accessible on that type.
Related: