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

Casting a extended class

Anthony Smith
Ranch Hand

Joined: Sep 10, 2001
Posts: 285
Let's say I have a class shape.

I extend it to make a class circle...

Well in my program, someone passes me a shape object... Now I want
to make it a Circle... How do I do so?

My logical way of thinking was to cast the shape object as a circle and
then set the circle members sort of like:

Shape s = returnShape(); //A shape object that has data is returned.
Circle c = (Circle)s; //Circle extends shape.

//Now do stuff with Circle
c.setRadius();

But I get a CLassCastException
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
That looks right to me if the object really is a Circle and Circle extends Shape. Maybe post some skeletal code from Shape & Circle so we can see more of what's going on?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Anthony Smith
Ranch Hand

Joined: Sep 10, 2001
Posts: 285
Ok, let me give real names now...


//This is my "Shape"
package gsptech.autopay.biz;

public class Awb {

public boolean isOda() {
return true;
}
}


//This is my Circle
package gsptech.autopay.biz;
public class RatedInboundAwb extends Awb
{
private double deliveryPaymentAmount;
private double deliveryWeightAmount;
private double deliveryOdaAmount;


public double getDeliveryPaymentAmount()
{
return deliveryPaymentAmount;

}

public void setDeliveryPaymentAmount(double deliveryPaymentAmount)
{
this.deliveryPaymentAmount = deliveryPaymentAmount;

}

public double getDeliveryWeightAmount()
{
return deliveryWeightAmount;

}

public void setDeliveryWeightAmount(double deliveryWeightAmount)
{
this.deliveryWeightAmount = deliveryWeightAmount;

}

public double getDeliveryOdaAmount()
{
return deliveryOdaAmount;

}

public void setDeliveryOdaAmount(double deliveryOdaAmount)
{
this.deliveryOdaAmount = deliveryOdaAmount;

}
}


//This is my code...
Awb a = new Awb();
RatedInboundAwb a2 = (RatedInboundAwb)awb;
Nigel Browne
Ranch Hand

Joined: May 15, 2001
Posts: 673
Why not create a constructor in your Circle class that excepts a shape as one of its arguments ?
Anthony Smith
Ranch Hand

Joined: Sep 10, 2001
Posts: 285
Ok, if I used this constructor in my Shape (RatedInboundAwb)

RatedInboundAwb(Awb awb)
{
//What do I put here?
}
Nigel Browne
Ranch Hand

Joined: May 15, 2001
Posts: 673
If your Awb class doesn't store any state, surely it would make more sense being an interface with a constant TRUE.
Anthony Smith
Ranch Hand

Joined: Sep 10, 2001
Posts: 285
Oh it does... I just left out all those other member variables and methods... Thanks though...
Nigel Browne
Ranch Hand

Joined: May 15, 2001
Posts: 673
Originally posted by Anthony Smith:
Ok, if I used this constructor in my Shape (RatedInboundAwb)

RatedInboundAwb(Awb awb)
{
//What do I put here?
}


I have written a quick example for you

I hope this helps
Arnaud Burlet
Ranch Hand

Joined: Oct 08, 2004
Posts: 31
Well, just to be sure let me recall that :

If Circle extends Shape, that means Circle is a special kind of Shape. (Circle is a specialisation of Shape.) That means every Circles are Shapes, but not the other way !

In your case, you get a Shape, okay ... it may be a Circle, but it may also be a Square. And when you get a ClassCastException, it means that your Shape is NOT a Circle. In that case the only way to get a Circle from your Shape is to do as Nigel advised, let a Circle be constructed from a Shape using a Circle constructor...

Ok, if I used this constructor in my Shape (RatedInboundAwb)


Oh well, in your example Shape is Awb and Circle is RatedInboundAwb, isn't it ? Let's assume that ...

If you used this constructor in your Circle (RatedInboundAwb):

RatedInboundAwb(Awb awb)
{
//What do I put here?
}

you have to assign to your newly created Circle all the common parameters with Shape. (I) in Nigel's example...


Arnaud
Anthony Smith
Ranch Hand

Joined: Sep 10, 2001
Posts: 285
I guess I see but my AWB is going to be huge... I mean 20+ member variables...

There has to be another way... I have have seen examples, but it must be something that I am doing wrong...

I do not understand why this would give me a class exception:

Awb a = new Awb();
RatedInboundAwb a2 = (RatedInboundAwb)a;
Arnaud Burlet
Ranch Hand

Joined: Oct 08, 2004
Posts: 31
this
Awb a = new Awb();
RatedInboundAwb a2 = (RatedInboundAwb)a;

gives you an exception because a is NOT of type RatedInboundAwb, so you can't cast (in java, casts are not done as in C...)

Why ... 3 ways to see it :
- You can't tell that all the Shapes are Circles, some Shapes are Squares, some are Stars ...
- You can't cast an Object to a String (that's exactly the same case as yours), because an Object lacks methods needed by String, like concat() substring() etc...
- The cast gives you an Exception because it cannot find the method a Circle should have in your Shape ! (maybe to C++ish but that's the principle)

In your example your Shape (Awb) has not the method getDeliveryPaymentAmount() all Circle (RatedInboundAwb) should have, that's why the cast fails.

About a huge Awb class ...reflection might be a way to do it, but ask other people before, I'm not sure about that !

Arnaud
Nigel Browne
Ranch Hand

Joined: May 15, 2001
Posts: 673
After a bit more thought. I believe that the following demonstrates what you are trying to achieve, which is runtume type identification of your downcast.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Casting a extended class