Greetings to JavaRanch! I have a question about references and class hierarchy (I hope my submitted code formats):
output: mammal mammal horse mammal.display() horse.display() Exception in thread "main" java.lang.ClassCastException This program generates a runtime exception when I try to make the assignment: secretariat = (Horse) animal; I wasn't expecting that error. Isn't this assignment the same kind of thing you do when you pull an object out of a Vector? Thanks in advance! (edited by Cindy to format code) [This message has been edited by Cindy Glass (edited August 26, 2001).]
The problem is simple really..but often hard to remember: You are attempting to cast a Mammal to a Horse. What you have to remember is that you can only cast down the tree of inheritance. Which really makes sense. Let me put it this way, you know that a Horse is a Mammal (Just like in the real world). This is casting up the inheritance tree. On the other hand, you cannot guarantee that a Mammal is a Horse. It could be a Monkey, a Human, or a Dog! This would be casting down the tree, and is invalid. A more technical example would be that the Horse object is really a composite of inheritance - it contains all that the Mammal contains PLUS any new methods,attributes of a Horse. Therefore, when you cast up to a Mammal, you are really only restricting the view of the object to that of the Mammal - which the Horse is anyway!
Joined: Aug 25, 2001
Thank you! My understanding is as yours, but I keep running into examples to the contrary: For instance, in "Java Software Solutions", the authors say: "If class Mammal is used to derive class Horse then a Mammal reference can be used to refer to an object of class Horse" Mammal animal; Horse secretariat = new Horse(); animal = secretariat; // valid assignment No problem so far, but they go on to say: "The reverse operation, assigning the Mammal object to a Horse reference, is also valid, but requires an explicit cast...
AHA!!! "The assignment is valid" mentioned above must simply mean that the java compiler will let it happen, which it does, but the fact is that the runtime environment will generate a ClassCastException when the assignment is executed. That's some crappy teaching of a basic topic by the authors of the aforementioned text book!
Thanks for the feedback.
Joined: Aug 25, 2001
Talking to myself: A downcast out of a Vector only works if the type of the being retrieved is in fact an exact match as the type of the object it is being assigned to, otherwise ClassCastException will be generated. Upcasts are always safe and don't need to be explicitly because they implicitly represent and "is a" relationship between the object being upcast and the object it is being upcast to.
Christopher The reason you got the error is because the Object you were casting to a Horse was not really a Horse. The compiler will let you make any up cast just fine, you dont even need to use a cast operator. On the other hand, when you are down casting you have to specify it with an explicit cast. In your case the line:
is telling the compiler that you want to take the object referenced by the animal variable and cast it to a Horse object. the compiler will not complain because it knows that horse is a subclass of Mammal (which is what the animal object was constructed as) so it assumes you know what your doing. You get the run time error because the animal abject is, in fact, a Mammal object not a Horse object. If you want the code to work as you want it to what you need to do is create the animal object from the Horse class. You can still store it in a Mammal variable (because it is still a Mammal too) but can convert it to a Horse also, because that is what it was created as. Here is your test class modified to let you do that: