aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes calling the right variable and method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "calling the right variable and method" Watch "calling the right variable and method" New topic
Author

calling the right variable and method

Rob Petterson
Ranch Hand

Joined: Jan 23, 2002
Posts: 149
Question ID 953430671680
public class TestClass
{
public static void main(String []args)
{
A o1 = new C( );
B o2 = (B) o1; //1
System.out.println(o1.m1( ) );
System.out.println(o2.i );
}
}
class A { int i = 10; int m1( ) { return i; } }
class B extends A { int i = 20; int m1() { return i; } }
class C extends B { int i = 20; int m1() { return i; } }
The answer is 30,20
I was in two minds as to this question.
I reasoned that it would produce the above result, however I had this doubt in my mind that it would throw a ClassCastException, due to line 1.I thought it would compile but would fail at runtime. Anyone explain?


Rob Petterson
SCJP
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
First off, the printed result is 20,20 and not 30,20.
The fact is that o1 is a reference of type A pointing to an object of runtime type C. Then, o1 is cast to B and referenced by o2 (of type B) which is perfectly legal. It is always allowed to reference an object of a subtype with a reference variable of a supertype. In clear, a C is_a specialization of a B which in turn is_a specialization of a A.
Then, the method m1 is resolved according to the runtime type of the variable, i.e. C. Field access is resolved according to the declared type of the variable (i.e. B).


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Rob Petterson
Ranch Hand

Joined: Jan 23, 2002
Posts: 149
I'm still confused with your answer.
If you removed: A o1 = new C();
would: B 02 = (B) o1; be legal?
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
If your remove that statement, where does o1 come from? I mean, in the second statement we have o1 and it has to be declared somehow...
Paul Villangca
Ranch Hand

Joined: Jun 04, 2002
Posts: 133
Of course not, 'coz then o1 wouldn't be declared.
It's easier to understand your code line by line.

A o1 = new C( );
Here, a reference of type A points to an object of type C, which is legal, since C is a subclass of A.

B o2 = (B) o1; //1
Here, o1 (which is a reference of type A) gets assigned to o2 (a reference of type B.) The cast is required since A is a superclass of B. At runtime, since o1 points to an object of type C (which is a subclass of B), it doesn't generate any ClassCastException.

System.out.println(o1.m1( ) );
Then, the method m1 is resolved according to the runtime type of the variable, i.e. C.

This means that the m1() method of C (the object pointed by o1) will execute, returning 20.

System.out.println(o2.i );
Field access is resolved according to the declared type of the variable (i.e. B).

Here, class B's i variable is returned.
Rob Petterson
Ranch Hand

Joined: Jan 23, 2002
Posts: 149

[ June 19, 2002: Message edited by: Rob Petterson ]
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
true, but the type of the object referenced by the variable must be assignment compatible with the variable to which it is assigned. In clear, o1, although having a declared type of A, is in fact and object of type C. Thus, an object of type C can be cast to B without any problem.
The problem mentioned in RHE can be shown with the following example:
A o1 = new A();
B o2 = (B) o1;
In this case, the compilation would be successful but at runtime you would get a ClassCastException since an object of runtime type A cannot be referenced by a variable of type B.
Casting is always allowed by the compiler since casting is a way of telling the compiler "I know what I'm doing, believe me."
Rob Petterson
Ranch Hand

Joined: Jan 23, 2002
Posts: 149
Right, I think it's sinking in.
I'll need to practice with it though.
Thanks for your help.
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
I'll need to practice with it though.
Right, practicing is the key to understanding. Don't hesitate to ask questions when in doubt
Francisco A Guimaraes
Ranch Hand

Joined: Mar 20, 2002
Posts: 182
Valentin, I have a doubt: in the first example, if you print o1.i you�ll get 10, why do you get 20 when you print o1.m1() ?


Francisco<br />SCJP<br />please use the [code][/code] tags when showing code.Click <a href="http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=ubb_code_page" target="_blank" rel="nofollow">here</a> to see an example.
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Because, as I said above, access to a variable is resolved according to the declared type of o1 and access to a method is resolved according to the runtime type of o1.
In A o1 = new C() the declared type of o1 is A and the runtime type of o1 is C. Thus, o1.i is 10 and o1.m1() yields 20.
[ June 20, 2002: Message edited by: Valentin Crettaz ]
Deepali Pate
Ranch Hand

Joined: Mar 20, 2002
Posts: 114
This i guess is what is called polymorphism in Java.
It states that variables are bound at compile time and methods are bound at runtime.
Considering the expample. At compile time the compiler only sees that o1 is of class type A it does not see that it is of type A but actualy holding type c. And since variables are bound at compile time it picks variable i from class A if u would print o1.i.
A o1 = new C( );
But if u asked to print o1.m1() it would print the value from C. Becoz at runtime it actually notices that o1 is of type C so it picks method from there.
This is very imp concept for exam. So get it cleared if u are palnning to take exams.
Francisco A Guimaraes
Ranch Hand

Joined: Mar 20, 2002
Posts: 182
I know that, but the method m1() returns i and i in o1 is 10 because o1 is of declared type A, so shouldn�t it return 10? or there are two values of i depending on how you call it?

Francisco
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Francisco,
note that each member variable i is local to the class it is declared in... method m1() of class B will return the value of the member i declared in class B. The same applies to A and C.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: calling the right variable and method