• Post Reply Bookmark Topic Watch Topic
  • New Topic

Casting of class types  RSS feed

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello!

There is one competent book ( let me note that they recommend JavaRanch also - http://www.ii.uib.no/~khalid/pgjc2e/resources.html )
where I found small example:

class Light { /* ... */ }
class LightBulb extends Light { /* ... */ }
class SpotLightBulb extends LightBulb { /* ... */ }
class TubeLight extends Light { /* ... */ }
class NeonLight extends TubeLight { /* ... */ }

public class WhoAmI {
public static void main(String[] args) {
boolean result1, result2, result3, result4, result5;
Light light1 = new LightBulb(); // (1)
// String str = (String) light1; // (2) Compile time error.
// result1 = light1 instanceof String; // (3) Compile time error.

result2 = light1 instanceof TubeLight; // (4) false. Peer class.
// TubeLight tubeLight1 = (TubeLight) light1; // (5) ClassCastException.

result3 = light1 instanceof SpotLightBulb; // (6) false: Superclass
// SpotLightBulb spotRef = (SpotLightBulb) light1;// (7) ClassCastException

light1 = new NeonLight(); // (8)
if (light1 instanceof TubeLight) { // (9) true
TubeLight tubeLight2 = (TubeLight) light1; // (10) OK
// Can now use tubeLight2 to access object of class NeonLight.
}
}
}

I thought that in lines (6)&(7) was true because light1 is the reference of the supertype Light and that it must be higher in the instanceof operator than type of the subtype SpotLightBulb (last one - lower - in the inheritance hierarchy). And the purpose of casting is to cast the supertype to the type of the subtype ( (<subtype> <supertypeRef> ),
but line (7) is invalid. Why? And in the instanceof operator where must be
<objectRef> in the inheritance hierarchy higher or lower than the target type ( <objectRef> instanceof <targetType> ) ?
And vice versa in lines (8),(9) I guess that here is executing the casting
of the subtype to supertype and that this casting can be execute by using an assignment: tubelight2 = light1;
Where are my thoughts wrong?
 
author & internet detective
Marshal
Posts: 37518
554
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
light1 is a LightBulb class. This means it is also a Light (because you can go up the hierarchy.) However, it is not a SpotLightBulb because that is lower in the hierarchy. This is similar to "a dog is an animal, but not all dogs are poodles."

The purpose of casting is to cast the supertype to the type of the subtype is to show that Java will give you an error. This is not something you want to do.

<objectRef> instanceof <targetType> - either can be higher. If objectRef is higher, it will return false. If targetType is higher, it will return true.
 
Oleg Korsakov
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Jeanne, for your answer but let me concretize a little to get
real clarification ...
So we have to cast LightBulb down to SpotLightBulb ( 'dog' to 'poodle' )
But it is not correct in that book. Is it correct really ?
( to cast to the type that is lower in the hierarhy )

And if objectRef is higher, it will return false ... then the downward
direction of casting will be lost. I guess we have to check to true before casting whether we can cast downward <objectRef> to <targetType> that is lower (i mean <targetType> here is a poople and objectRef here refers to a dog so let me guess that 'dog instanceof poodle' gives 'true')
 
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A cast of a reference type never changes the actual object; it only changes the compiler's idea of what the reference points to. If an object was created with "new LightBulb()", then it is a LightBulb, but is not, and never can be, a SpotLightBulb.

If, on the other hand, an object was created with "new SpotLightBulb()", then it is a SpotLightBulb, which is a kind of LightBulb, and you can have a variable of either of these types pointing to it. If you have a variable of type LightBulb pointing to a SpotLightBulb, and you want to tell the compiler that it's really a SpotLightBulb, then you can use a cast; but the cast doesn't change the object at all.
 
Oleg Korsakov
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My special thanks to Ernest too, especially in "A cast of a reference type never changes the actual object".
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!