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

casting

frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
When I cast a superclass object to a subclass variable I get a runtime error. Why doesn't this happen with Graphics2D, which is a sublcass of Graphics, in the code below :
public void Paint (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
}
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
You don't get a runtime exception if the object is of the subclass type. You've discovered that on your machine, the automatic Graphics object is also a Graphics2D object.
Remember, you can refer to an object of the subclass with an identifier that is of the superclass type, and you can also cast the object back down to the subclass (of which it already belongs).
Perhaps a bit disjointed of an explanantion, but making sense?


[How To Ask Good Questions] [JavaRanch FAQ Wiki] [JavaRanch Radio]
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
Originally posted by Dirk Schreckmann:
the automatic Graphics object is also a Graphics2D object.]

how can Graphics be a Graphics2D object, i thought Graphics2D extended
Graphics?

Remember, you can refer to an object of the subclass with an identifier that is of the superclass type, and you can also cast the object back down to the subclass (of which it already belongs).

can you give a code example where this works in the form of :
subclass sub = (subclass)superclassObject;
[ May 27, 2002: Message edited by: herb slocomb ]
[ May 27, 2002: Message edited by: herb slocomb ]
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
Regarding the example code, you've already posted one example.
Here's another example to consider:

One concept to realize here is that not all animals are zebras, but some animals may be zebras. Not all Graphics objects are Graphics2D objects, but some Graphics objects may be Graphics2D objects. Not all super class objects are also of a particular subclass type, but some super class objects may also be of a particular subclass type.
[ May 27, 2002: Message edited by: Dirk Schreckmann ]
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
Originally posted by Dirk Schreckmann:
.

some super class objects may also be of a particular subclass type.
[ May 27, 2002: Message edited by: Dirk Schreckmann ]


The example you give doesn't really have the form
subclass sub = (subclass)superClassObject; since
you have only created one object type and that was a Subclass object.
In my original example, I guess Graphics g is really a Graphics2D object is what you are saying, but how the heck does it become one?
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
The example you give doesn't really have the form
subclass sub = (subclass)superClassObject;

Um, look again:
SubClass subClassObject2 = (SubClass)superClassObject ;
The automatic Graphics object is much more than merely a Graphics2D object. Note that the classes Graphics and Graphics2D are both abstract classes. These classes cannot be instantiated. An object that is of type Graphics and/or Graphics2D must then also be of some other subclass that is not abstract and can be instantiated. Test this code on your system and discover just what your automatic Graphics object is:

Not what you expected?
This automatic java.awt.Graphics object is different on different systems. The web browser or applet viewer is responsible for creating this object and passing it to the paint method. One important thing to note is that this object must be a subclass of java.awt.Graphics. Which subclass may change from system to system. Thanks to polymorphism, we programmers don't have to worry what this subclass is - we just program for objects of type java.awt.Graphics.
[ May 27, 2002: Message edited by: Dirk Schreckmann ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Another example (caution, I didn't try to compile this ):

Notice that myObject2 is refering to an instance of MyClass2. So if you pass it to do(), myParam is refering to an instance of MyClass2, too, therefore the cast is working.
Casting an object reference from X to Y is nothing more than telling the compiler "Well, I know I said that we have an X here, but I really think it is in fact at least an Y (which is a subclass of X). Of course we can only know for sure at runtime, so would you please create the code that tries to convert the reference and throws an Exception if I was wrong? Thanks!"
Does that help?
[ May 28, 2002: Message edited by: Ilja Preuss ]

The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
Originally posted by Dirk Schreckmann:
The example you give doesn't really have the form
subclass sub = (subclass)superClassObject;

Um, look again:
SubClass subClassObject2 = (SubClass)superClassObject ;


But in your example, doesn't the superClassObject actually refer to a subclass object since no other object has been created in the code you gave??? Casting something doesn't really doesn't change the type of the object does it ???


[b]
The automatic Graphics object is much more than merely a Graphics2D object. Note that the classes Graphics and Graphics2D are both abstract classes. These classes cannot be instantiated. An object that is of type Graphics and/or Graphics2D must then also be of some other subclass that is not abstract and can be instantiated. Test this code on your system and discover just what your automatic Graphics object is:

Not what you expected?
This automatic java.awt.Graphics object is different on different systems. The web browser or applet viewer is responsible for creating this object and passing it to the paint method. One important thing to note is that this object must be a subclass of java.awt.Graphics. Which subclass may change from system to system. Thanks to polymorphism, we programmers don't have to worry what this subclass is - we just program for objects of type java.awt.Graphics.
[ May 27, 2002: Message edited by: Dirk Schreckmann ]


I see what you mean, the applet viewer said it was a sun.java2d.SunGraphics2D class (it didn't display anything when I viewed the page using IE 5.5). I don't understand the details of how this Graphics object is created. There should be some code somewhere we could view (unless its like the code that creates the "out" object in System.out which I could never find).
But if the abstract class Graphics had been extended only and the class was not of type Graphics2D then we do have a PROBLEM which was my original point. Programmers DO have to be concerned with these issues since polymorphism won't save the day in those cases where we are trying to downcast a real superclass object into a sublclass type variable. In my sample code this always creates a runtime error when this happens : SubClass subClassObject2 = (SubClass)superClassObject ;
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
Here's the simplest code that illustrates my question :
class sup {};
class sub extends sup {
public static void main(String a[]) {
sup SUP = new sup();
sub SUB = new sub();
SUB = (sub)SUP;
}
}
Compiles fine, but you get a ClassCastException. Now my original point was why doesn't this happen when we do this :
public void Paint (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
}
Dirk pointed out that Graphics and Graphics2D are abstract and therefore its possible that an object could be of both types. My concern was I thought g was of type Graphics only and this should cause a runtime error just like my sample code above. Dirk said the type of Graphics object created may vary, but if it is ever not of type Graphics2D and only of Graphics we may have a problem just like my sample code.
[ May 28, 2002: Message edited by: herb slocomb ]
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
I'm not the only one thinks the code below looks strange.
public void Paint (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
}
Cay Horstmann, author of Core Java and other Java books, calls it a sign of not good programming and a quick fix for a compatibility problem.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
It's not that unusual to be passed a parent of the class that you are really interested in. I would put an instanceof just to prevent runtime problems:


Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Thomas Paul:
It's not that unusual to be passed a parent of the class that you are really interested in. I would put an instanceof just to prevent runtime problems: [...]

On the other hand, if the method can only do its work by using a Graphics2D, a ClassCastException might in fact be the appropriate answer to a Graphics object...
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: casting