posted 23 years ago
Note that A extends B, so A inherits m1() and overrides m1(int) from A. The methods will be picked up based on signature and object type.
Let's keep a record of A.x and B.x values after each statement:
>>> A.x = 0, B.x = 0 //class initialization
B(){ x = 10;}; // This implicit super() call is invoked every time a new A() is created.
>>> A.x = 0, B.x = 10
B x = new A();
>>> A.x = 20, B.x = 10
System.out.println(x.x); >>> prints 10 (B.x) because x is a supertype type. Variables are picked up strictly based on reference type.
x.m1(); // m1 in B is invoked because it matched the signature.
>>> A.x = 20, B.x = 20
System.out.println(x.x); >>> prints 20 (B.x) because x is a supertype type. Variables are picked up strictly based on reference type.
x.m1(30); // m1 in A is invoked because it matched the signature, and the method is non-static and overriding. Dynamic method binding applies: Method is picked up based on object type.
>>> A.x = 20, B.x = 30
System.out.println(x.x); >>> prints 30 (B.x). Variables are picked up strictly based on reference type.
((A)x).m1(30); // The casting changes the reference type from supertype to subtype. m1 in A is invoked because of its object type, not because of the casting.
>>> A.x = 20, B.x = 30
System.out.println(x.x); >>> prints 30 (B.x) because x is a supertype type. Variables are picked up strictly based on reference type. The casting in the preceding statement is transient, does not hold through the following statement.
[ April 16, 2002: Message edited by: Doanh Nguyen ]
[ April 16, 2002: Message edited by: Doanh Nguyen ]