I'm studying Java and I was given the following code:
public class A {
    public void m(A a) { System.out.println("A.m:A"); }
    public void m(B b) { System.out.println("A.m:B"); }
}
public class B extends A {
    private void m(C c) { System.out.println("B.m:C"); }
    public void m(B b) { System.out.println("B.m:B"); }
}
public class C extends A {
    public static void main(String args[]) {
        A ab = new B();
        B bb = new B();
        A ac = new C();
        ab.m(ac); // My answer: A.m : A || correct
        ab.m(ab); // My answer: B.m : B || Correct answer: A.m : A
        ab.m(bb); // My answer: B.m : B || correct
        bb.m(ac); // My answer: compile error || Correct answer: A.m : A
        bb.m(ab); // My answer: B.m : B || Correct answer: A.m : A
        bb.m(bb); // My answer: B.m : B || correct
        ac.m((A)bb); // My answer: A.m : A || correct
        bb.m((B)ac); // My answer: compile error || Correct answer: run-time error [Class cast exception] --> I UNDERSTAND THIS
        bb.m((B)ab); // My answer: B.m : B || correct
    }
}
I had to write what would be the result of the calls in main function. As you can see I got most answers wrong. What I'm trying to understand is how can I determine what class function is called when I have a variable of the type of the superclass that is created with the constructor of a subclass?
 
     
    