aspose file tools*
The moose likes Java in General and the fly likes Object Reference Conversions Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Object Reference Conversions" Watch "Object Reference Conversions" New topic
Author

Object Reference Conversions

Andrew Keidel
Greenhorn

Joined: Dec 06, 2001
Posts: 27
Several references have said that object reference conversions do not cause a compiler error when it's from a class to its superclass. Alternatively, if you try to assign a class to its subclass, you need a cast.
Why is this so? The fact that primitive conversions must be widening if they are without a cast makes easy sense. But for classes, it seems that Java forces the opposite rule. Assigning from subclass to superclass means that some of the variables in the subclass that are not in the original superclass will be lost; this seems to be like a narrowing conversion. On the other hand, assigning from a superclass to a subclass would seem to retain all the variable info from the superclass, since this is all contained in the subclass which extends it.
Does access (public/private/etc) have anything to do with the reasons for this counter-intuitive rule?
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Andrew
I undertstand what you're saying, in fact when I first got into Java it sometimes took me awhile to figure that out (sometimes I still have to think about it ).
I think the reasons are in a few parts, the first part is the 'is a' relationship between a subclass and its super class. Any instance of a subclass 'is a' kind of its super class, so you can change a subclass into its superclass because it is the same type.
Another part may have to do with storage and the member variables an instance has. When they are created, objects get allocated storage for all of their member variables so an instance of a subclass has all of its variables and all of the variables of its superclas so it can act like and react to all of the things its superclass can. On the other hand, the superclass object only has its own variables and none of the members from it sub classes - in fact it doesn't know anything about its subclasses, so it can't act like them.
When you cast a subclass to its superclass it is consiodered a widening conversion, I justify this to myself by saying that you are taking the subclass and making it less specific, it can be used in a wider variety of situations so it is a widening coversion. Going from a superclass to a subclass is narrowing because you're reducing the objects usefullness it has a narrower scope now.
I dont't know if that helped you or not, hope it did. I'm sure someone else can give a better explaination

------------------
Dave
Sun Certified Programmer for the Java� 2 Platform


Dave
Andrew Keidel
Greenhorn

Joined: Dec 06, 2001
Posts: 27
Thanks.
Another thought... let me know if this makes sense. Assume you have a class (Fruit) and two subclasses (Orange and Pear). Now check out the following code:
class Fruit {}
class Orange extends Fruit {}
class Pear extends Fruit {}
public class test {
public static void main(String args[]) {
Fruit fruit = new Fruit();
Orange orange = new Orange();
fruit = orange;
Pear pear = (Pear) fruit;
}
}
For the {fruit = orange;} part of the code, you don't need a cast and for the {pear = (Pear) fruit;} part you do. But assume for a moment that you didn't need a cast when assigning from a class to its subclass. Then you could write {pear = fruit;} without a cast. But what you would be doing, effectively, is assigning an orange to a pear (since fruit has been assigned to an orange in the previous line), and this does not make much sense. Since this does not make sense, the compiler should require a cast (implying that the code is as intended), and that's exactly what the compiler does.
Correct me if I'm wrong, but when you assign {fruit = orange;}, we are not really losing any orange-specific information; it's just that we need to cast the fruit back to an orange to get that info out of it. That's why it's fine to leave out the cast when making this assignment (b/c no info is lost and b/c an orange "is a" fruit).
But when we try to assign {pear = fruit;}, we don't know if fruit is really a pear, or if it's some other kind of fruit. Therefore, we need to tell the compiler that we know what we're doing, so we use a cast.

Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Andrew
When you convert from a subclass to its superclass you're correct, your dont lose anything from the original object. In fact all of the methods would still be called on the subclass object because of run time binding. The objects variables and static methods however, would be called using the superclass type as indicated by the reference type of the variable that holds the object.
So, yes, your correct in order to access an objects variables (and static methods) it has to be held by a variable that holds that type of reference.
When we down cast from the superclass to the subclass type all that is required is that the objects be of the same type or be related to each other - that's all the compiler checks for. You can still get a runtime error (as you would in the example you gave) if the object being cast is not really of the type it is being cast to.
The JLS section 5.2 might help you out a little although it doesn't really get into the internal working of it.
hope that helps

------------------
Dave
Sun Certified Programmer for the Java� 2 Platform
 
Consider Paul's rocket mass heater.
 
subject: Object Reference Conversions