aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Casting down the hierarchy 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 "Casting down the hierarchy" Watch "Casting down the hierarchy" New topic
Author

Casting down the hierarchy

d jones
Ranch Hand

Joined: Mar 13, 2006
Posts: 76
Hi

I got the following question from about.com but I don't fully understand the answer.

class FourWheeler implements DrivingUtilities
class Car extends FourWheeler
class Truck extends FourWheeler
class Bus extends FourWheeler
class Crane extends FourWheeler

Consider the following code below:
1. DrivingUtilities du;
2. FourWheeler fw;
3. Truck myTruck = new Truck();
4. du = (DrivingUtilities)myTruck;
5. fw = new Crane();
6. fw = du;

Then the following statemnt is considered true:
The code will not compile without an explicit cast at line 6, because going down the hierarchy without casting is not allowed.

Why do they say that we are casting down the hierarchy at line 6.
fw is a reference varaiable for a FourWheeler object.
du is a reference variable which stores a reference to an object implementing the DrivingUtilities interface.

fw can refer to any of its subclasses which implement the du interface. Why would the compiler complain about this? I would have thought that it should compile okay and throw a ClassCastException if there were a problem.

Many Thanks
Charith Fernando
Ranch Hand

Joined: Sep 12, 2005
Posts: 67
take Object and String as an example....

Object is the super class and the String is the sub class....

if you want to assign a String to an Object you dont need a cast. because simply you can assign any subclass to a reference of one of it's superclasses...



when you want to convert this 'a' into a String or when you want to assign the object to a String reference as follows, then you need a cast...

WHY?

because at compile time, the compiler is not aware of the object it holds and therefore needs a cast to say... "I know this reference holds a String for sure" to ensure this you can run an instanceof condition.

the compiler only worries about the reference type not the object type....

a ClassCastException may occur if you assign an Integer to an Object reference and try to cast it to a String.

if you try to do this, you wont get any compilation errors because at compile time JAva just checks whether it can convert an Object to a String.. but at real or at runtime the real Object is an Integer.. and an Integer cannot be casted to a String...

ask if its not clear....


Charith I Fernando<br />SCJP5, SCWCD, SCBCD, BSc(Hons) IS<br />+94 773 263 222 (mobile)
Charith Fernando
Ranch Hand

Joined: Sep 12, 2005
Posts: 67
just thought i would add some more....

JUST dont worry about the Objects which a reference holds at compile time.. just concentrate on the reference variable types at compile time... if you just think like in this way then you would know whether the code will compile or not... if the code tries to assign an Object reference to a String reference you always need a cast because the compiler does not gaurantee that whats in there in that reference is really a String...

at RUNTIME: think about the Objects.. if the Object reference held an Integer and if you try to cast it to a String then a ClassCastException may get thrown...

though the following code does not work at runtime it will compile fine...

d jones
Ranch Hand

Joined: Mar 13, 2006
Posts: 76
Thanks Charith

I'm still not 100% clear.

What does 'casting down the hierarchy' mean in the above example?

Many Thanks
Charith Fernando
Ranch Hand

Joined: Sep 12, 2005
Posts: 67
visualize it ......

class FourWheeler implements DrivingUtilities

means

FourWheeler ---- >>>>> DrivingUtilities

and you're trying to assing a 'DrivingUtilities' reference into a FourWheeler reference... so think who's at the top of the hierarchy...

DrivingUtilities is in the top and FourWheeler is in the bottom.. which means if you're trying to assign a superclass reference into a subclass reference you're you need to cast it... or down cast it...

hope you got it
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

See if these topics from Bruce Eckel's Thinking in Java help:
  • Upcasting
  • Downcasting and run-time type identification


  • "We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
    sscce.org
    David Kennedy
    Ranch Hand

    Joined: Jan 22, 2006
    Posts: 33
    Im wondering is the Cast at line 4 necessary.
    Im guessing that it isnt?

    and you could just do


    du=mytruck;


    "There are only 10 types of people in the world: Those who understand binary, and those who don't"
    Burkhard Hassel
    Ranch Hand

    Joined: Aug 25, 2006
    Posts: 1274
    Hi cowboys,


    if the last line were
    fw = (FourWheeler)du;


    It would compile.

    Special service for home tests:


    compiles and runs without exception

    du is of reference type DrivingUtilities (the reference type of the interface) it stores an object that was a Truck. That's possible, since Truck IS-A DrivingUtility (Truck extends FourWheeler and 4Weeler implements D.Ut.).

    fw is of reference type FourWheeler. In the last but one line, fw stored a Crane object, but that's not important. In the last line fw is dereferenced to the du variable.
    It needs an explicit cast, because du is of an interface type.

    If you cast from implementer to interface, it is an upcast.
    The other way round is a downcast, that needs an explicit cast.




    Easier example, castings between interfaces an implementers



    In the upper example, you can cast implicitely from an implementer to its interface. It is always clear, that a class that implements an interface also has its methods.

    But in the example with variable sandy, you have to cast manually. Otherwise, the code would not compile. It is not sure, that a Swimable IS-A BlueTang. Could also be a ClownFish or a Dolphin.


    That you have to put a casting manually makes sense, since it is possible that such a interface -> implementer casting could cause a class cast exception (what the code here does not do).

    But if you set up a class, say ClownFish, that implements Swimable, and you wrote:
    ClownFish nemo = (ClownFish) swimmer;
    you get a ClassCast Exception. Because swimmer stored a BlueTang, not a Clowny.




    Yours,
    Bu.


    ---
    Palette surgeonfish and Blue tang are the same


    all events occur in real time
    marc weber
    Sheriff

    Joined: Aug 31, 2004
    Posts: 11343

    Originally posted by David Kennedy:
    Im wondering is the Cast at line 4 necessary.
    Im guessing that it isnt? ...

    That's correct. But there's no need to guess. A quick test will confirm...
     
    Consider Paul's rocket mass heater.
     
    subject: Casting down the hierarchy