It's not a secret anymore!*
The moose likes Beginning Java and the fly likes DownCasting Generally Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "DownCasting Generally" Watch "DownCasting Generally" New topic
Author

DownCasting Generally

Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
I have some basic casting questions that I need to be sure I'm clear about, since it appears some of my earlier sources are innacurate. I would appreciate it if someone could correct me where I'm wrong or fill in the blanks.
1.
class C extends A
A a1 = new A()
c c1 = new C()
a1 = (A)c1
Coersive assignment of child type to parent will always compile, however is the (A) casting operator ALWAYS required?
2.
class B extends A
A a1 = new A()
B b1 = new B()
b1 = (B)a1
Here this downcast assigment of parent to child must always have the (B) cast, however, it MAY not compile, it depends.
3.
class Y extends X
X myX = new X()
y myY = (Y)myX
Another downcast assignment of obj ref var of parent assigned to just a child type Y which was never instantiated y myY = new Y(). This compiles ok, however it child were instantiated Cast (Y) MUST exist, and there may or may not be a compiler error as in ques #2.
4.
class Y extends X
y myY = new Y()
x myX = myY
Another Coersive assignment of child type to parent which will always compile, even if the parent were instantiated as in ques #1 ie
x myX = new X(). A mock exam indicated this is legal, however child cast (Y) is glaringly absent. Therefore should I assume that the child cast operator is optional?
TIA
Shivaji Marathe
Ranch Hand

Joined: Jan 11, 2002
Posts: 203
Paul :
You can actually write simple classes and try these options out yourself.
I believe that is the best way to unserstand the difference between casting ( explicit ) and
conversion ( implicit ).
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
ok. first let me say that u can post this message in the programmer certification study as ull get there better answer than mine
now for my answer:
1. a reference of the parent can always refer to an object of one of the sublasses(the child).
you dont need to use the (A) casting as it work without - upcasting is done automatically.
it will compile and run fine.
2. for downcasting (parent to child) u need to write the cast yourself, so u were correct to write (B) .
now for the tricky part, during compilation it will ALWAYS compile because when the compiler compiles it ONLY checks to see if the child (in this case B) is subclass of parent (A).
BUT in runtime (while the program runs) in this case it will throw an error. the reason for this is because at runtime a1 doesnt actually refer to (points to) an instance of B.
3. same goes here as 2! it will always compile (y is subclass of X) - u have to use explict cast (parent to child) BUT at runtime again it will throw error cause myX doesnt refer at runtime to an instance of Y.
4. compile and run fine, no casting is needed like in 1 (upcasting child to parent).
i will add another option to demonstarte some more:
5. class Y extends X
X myX=new Y(); //myX can refer to an
instance of Y (upcasting)
Y myY=(Y)myX;
this will compile ( u need to explict casting ) BUT it will also work fine in runtime (NO exception) cause at runtime myX actually refer to an instance of Y.
phew!
hope i made it less messier, like i said im not that good in explaining
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Roy Ben,
3. same goes here as 2! it will always compile (y is subclass of X) - u have to use explict cast (parent to child) BUT at runtime again it will throw error cause myX doesnt refer at runtime to an instance of Y.

What about the fact that in #3 there is no constructor for the child type?? myX parent type is being assigned to Y myY which is not an instantiated subclass obj??
All the other points are clear so far (great explanation) until I run into JQ+ things
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
glad u liked it
about point 3.
u need to understand the difference between creating an object in memory with the new operator and creating a reference.
in point 3 u create an Object from class X and u refer to it by the refrence myX.
then u create another refrence called myY which "thinks" it should refer to objects of class Y.
BUT u tell it to refer to an object (instance) of class X and to do that u need to use casting (cause its parent to child).
this only creates another refernce to the same object. so u get myY and myX which point to the same object.
HOWEVER, like i said this will pass compilation (because the compiler only checks to see if Y is a child of X and then he allows the casting), but in runtime u'll get an error, cause myX doesnt actually refer to an object of the Y class so the casting will fail.
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
just another note:
notice the point 5 i gave u in my post before.
point 5 is exactly the same as point 3 but i use
X myX=new Y() instead of new X().
thats why in point 5 it will pass both compilation and runtime.
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Roy Ben,
So in point 3 if the subclass were instantiated ie Y myY = new Y() of which it is not now, basically the results would be the same just as refering to an obj reference. same results for both: compiles ok but Runtime error?
before:
class Y extends X
X myX = new X()
Y myY = (Y)myX
after:
class Y extends X
X myX = new X()
Y myY = new Y()
Y myY = (Y)myX
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
correct .
just the last line should read :
myY=(Y)myX;
and not:
Y myY=(Y)myX;
because u already declared a variable named myY.
Also, in the second case the object u created with the new operator for the Y (the new Y())
will get GC (garabage collected) because there will be no more refrences which refer to it.
but again to answer your basic question yes it will be the same
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Roy Ben,
This portion of casting appears crystal clear. I wanted to add one more code snippet in this thread since its associated with the same sort of downcasting.
I need to nail down this relationship in terms of variables being shadowed.
Here's a previous example:
1.

Here I think we're accessing B's variables and methods since we casted.


I've seen some examples where the variable is determinant upon the type, here c1 is of type C. The opposite holds true for methods which are defined by object type, here c1 assigned type d1 D() type.
Am I missing anything here?
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
you are again correct in your assumption.
Think like this:
first of all the compiler goes ALWAYS to the refrence type so in the first one he goes first to class B and in the second to class C.
thats why the variables will be of B in the first and of C in the second.
however, lets see what happens in methods.
because in java there is somthn called polymorphism, if it goes to C and see that there is an overriden method (the exact same method) at what it actually refers to (in this case an object of D) then it will do the method in the D.
so remember it always goes first to the refrence type then checks there. if it is a method and u have the exact same method in the subclass that u actually refer to, it will do that.
if i didnt explain too good ask again
Paul Salerno
Ranch Hand

Joined: Jan 17, 2002
Posts: 172
Roy Ben,
This was a brilliant explanation, we can now close this issue. Appreciate your help
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: DownCasting Generally
 
Similar Threads
Object casting
Rules Roundup game
Ques on casting referances ...
this roundup question trips me up every time
Please explain these answers