Search code examples
javadynamic-bindingstatic-binding

Binding in Java (overriding methods and "fields")


public class Print1 {
    int x = 1;
    public void print(A a) { System.out.println(x); }
    public void print(B b) { System.out.println(x+1); }
}      

public class Print2 extends Print1 {
    int x = 3;
    public void print(A a) { System.out.println(x); }
    public void print(B b) { System.out.println(x+1); }
    public void print(C c) { System.out.println(x+2); }
}

// a tester class with main method 
A a = new A(); B b = new B(); C c = new C();
Print1 p1 = new Print1();
Print2 p2 = new Print2();
p1 = p2;

 System.out.println(p1.x); // Call 1, p1 is from Type Print1
 p1.print(c); /* Call 2
 //p1 is from Type Print2, print(B b) will be called */`

Class B is a subclass of Class A and C is a subclass of B.

  1. why in Call 1 P1 from type Print1 even though it is referencing to Object of type Print2 and in call 2 it is behaving as reference to Print2-object?

  2. why in Call 2 print(B b) is called from Print2 and not print(C c)?

This is the most confusing things for me so far in Java. Thank you for your help.


Solution

  • The type of the variable is used to determine the class member that is accessed.

    Therefore p1.x refers to the x field in Print1, not the one in Print2. (it would result in a compile time error, if you removed x from Print1.) The x field in Print2 is a different field, i.e. Print2 objects have 2 different int fields.

    Also the print(B b) method is used in the expression p1.print(c) since Print1 doesn't have a method print(C c). (It would be a compile time error, if C wouldn't extend B or A.) Since Print2 overrides the implementation of Print1.print(B b), that implementation is used.