d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Typecasting From Superclass To Subclass > Halp!
Add Reply New Topic New Poll
Member
Posts: 12,005
Joined: Sep 7 2005
Gold: 9,460.01
Feb 15 2014 08:09am
JAVA

I'm having an issue here with trying to get my superclass to be a subclass.

I currently have an object:

Car car = new Car();

This car needs to have the methods of it's subclass Audi.

Audi audi = new Audi();

However typecasting it like this doesnt work

audi = (Audi)car;



Any suggestions on how to work this out? It's not possible to create the initial Car object as an Audi to begin with.

This post was edited by GeekS on Feb 15 2014 08:10am
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Feb 15 2014 10:26am
Quote (GeekS @ Feb 15 2014 09:09am)
JAVA

I'm having an issue here with trying to get my superclass to be a subclass.

I currently have an object:

Car car = new Car();

This car needs to have the methods of it's subclass Audi.

Audi audi = new Audi();

However typecasting it like this doesnt work

audi = (Audi)car;



Any suggestions on how to work this out? It's not possible to create the initial Car object as an Audi to begin with.


i assume this is a homework assignment, in which case @bolded you misread your requirements. post your exact requirements, word for word.

in java, the methods you have available at runtime are based solely on your object type, the class whose constructor you invoked (eg: new Audi() or new Car()).
if you wanna be able to call the methods from the Audi class, then you must have an object of the Audi class or an object of a subclass of Audi. Since Car is neither, you can never call the methods from Audi.

Changing the reference type (eg: the type of the variable) only tells the compiler what is available. ex:
Car c = new Audi();
// Car is the reference type, so you can only call methods in Car, not methods in Audi
Audi a = (Audi)c;
// this is a valid cast; now you can call any methods of Audi

In java, you can not magically add new methods to an existing class at runtime as far as i'm aware. (possibly if you mess with custom class loading, but beyond the scope of any beginner's homework assignment). so if you create a Car object (eg: new Car()) then you can never call methods that exist in Audi

This post was edited by carteblanche on Feb 15 2014 10:30am
Member
Posts: 1,241
Joined: Jun 25 2011
Gold: Locked
Feb 15 2014 10:28am
If it's not possible to do Car car = new Audi() it means that Audi does not extend Car, therefore the cast doesn't make any sense. If you really want to treat car as an Audi, you'll have to apply the Adapter pattern. However we can't show you how if you don't post the full code we're working on
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Feb 15 2014 07:33pm
Code
public abstract class Animal
{
public abstract void say();
}


public class Cow extends Animal
{
public void say()
{
System.out.println("Moo!");
}
}

public class Fish extends Animal
{
public void say()
{
System.out.println("Blub");
}

}

public class Fox extends Animal
{
public void say()
{
System.out.println("Ring-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding!");
}
}



public class AnimalTest
{
public static void main(String[] args)
{
Animal animal;

//what does the cow say?
animal = new Cow();
animal.say();

//what does the fish say?
animal = new Fish();
animal.say();

//what does the fox say?
animal = new Fox();
animal.say();

}

}
Member
Posts: 3,580
Joined: Aug 17 2013
Gold: 275.01
Feb 17 2014 01:16pm
Quote (Minkomonster @ Feb 15 2014 10:33pm)
Code
public abstract class Animal
{
    public abstract void say();
}


public class Cow extends Animal
{
      public void say()
      {
            System.out.println("Moo!");
      }
}

public class Fish extends Animal
{
    public void say()
    {
          System.out.println("Blub");
    }
 
}

public class Fox extends Animal
{
    public void say()
    {
          System.out.println("Ring-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding!");
      }
}



public class AnimalTest
{
    public static void main(String[] args)
    {
            Animal animal;

            //what does the cow say?
            animal = new Cow();
            animal.say();

            //what does the fish say?
            animal = new Fish();
            animal.say();

            //what does the fox say?
            animal = new Fox();
            animal.say();
         
      }

}


NOO!! OH GOD NO!! MAKE IT STOPPP!!!!
Member
Posts: 12,005
Joined: Sep 7 2005
Gold: 9,460.01
Feb 21 2014 11:05am
Quote (carteblanche @ 15 Feb 2014 18:26)
i assume this is a homework assignment, in which case @bolded you misread your requirements. post your exact requirements, word for word.

in java, the methods you have available at runtime are based solely on your object type, the class whose constructor you invoked (eg: new Audi() or new Car()).
if you wanna be able to call the methods from the Audi class, then you must have an object of the Audi class or an object of a subclass of Audi. Since Car is neither, you can never call the methods from Audi.

Changing the reference type (eg: the type of the variable) only tells the compiler what is available. ex:
Car c = new Audi();
// Car is the reference type, so you can only call methods in Car, not methods in Audi
Audi a = (Audi)c;
// this is a valid cast; now you can call any methods of Audi

In java, you can not magically add new methods to an existing class at runtime as far as i'm aware. (possibly if you mess with custom class loading, but beyond the scope of any beginner's homework assignment). so if you create a Car object (eg: new Car()) then you can never call methods that exist in Audi


Quote (m0hawk @ 15 Feb 2014 18:28)
If it's not possible to do Car car = new Audi() it means that Audi does not extend Car, therefore the cast doesn't make any sense. If you really want to treat car as an Audi, you'll have to apply the Adapter pattern. However we can't show you how if you don't post the full code we're working on


Sorry i haven't replied earlier, figured i have to rework my entire program due to what you mentioned here. This is however not an assignment, i just figured it would be easier explaining my situation using the Car&Audi objects :P.

Quote (Minkomonster @ 16 Feb 2014 03:33)
Code
public abstract class Animal
{
    public abstract void say();
}


public class Cow extends Animal
{
      public void say()
      {
            System.out.println("Moo!");
      }
}

public class Fish extends Animal
{
    public void say()
    {
          System.out.println("Blub");
    }
 
}

public class Fox extends Animal
{
    public void say()
    {
          System.out.println("Ring-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding! Gering-ding-ding-ding-dingeringeding!");
      }
}



public class AnimalTest
{
    public static void main(String[] args)
    {
            Animal animal;

            //what does the cow say?
            animal = new Cow();
            animal.say();

            //what does the fish say?
            animal = new Fish();
            animal.say();

            //what does the fox say?
            animal = new Fox();
            animal.say();
         
      }

}


This was actually exactly what i've been looking for. The issue is that you can only create animals as new objects of say fish, not typecast it if the fish has already been instantiated.

Car car = new Car();
car.setColor("red");
Audi audi = (Audi)car;
// This does not work :p


However ty everyone for the help, it's nice knowing that i didnt spend my time rewriting shitton of code for nothing :<
Member
Posts: 1,241
Joined: Jun 25 2011
Gold: Locked
Feb 21 2014 12:05pm
I think you're misunderstanding the concepts behind class heritage and polymorphism.
Okay first you should not instanciate the type Car because it is an abstract type (cannot be instanciated). This means that you've "factored" all the code that is common across Audi, Mercedes etc in one class so you wouldn't have to say "An Audi has a model name, a registration plate number etc..." then, again "A Mercedes has a model name, a registration plate number etc..."

Instead, using an abstract Car class, you're basically saying "A Car has a model name, a plate number etc", and Audi and Mercedes are both Cars (they "extend" Car, just like Cow extends Animal).

So you can see that trying to do Car car = new Car() and Audi audi = (Audi)car makes no sense because you're trying to cast an abstract type to a "concrete" type. The correct way to do this is the other way around, eg

Code
Car audi = new Audi(); //an Audi object with the Car type, you have access the Car methods (setColor(), getModelName(), getPlateNumber() etc)
audi.setColor("red");


So your classes should look something like this:

Code
public abstract class Car { // Notice the use of abstract
private String color;
public void setColor(String color) {
this.color = color;
}
//code that is the same across all cars goes here
}

public class Audi extends Car { // A concrete implementation of a car
//code that is specific to the Audi cars goes here
}


Hope it helped

This post was edited by m0hawk on Feb 21 2014 12:15pm
Member
Posts: 12,005
Joined: Sep 7 2005
Gold: 9,460.01
Feb 21 2014 12:26pm
Quote (m0hawk @ 21 Feb 2014 20:05)
I think you're misunderstanding the concepts behind class heritage and polymorphism.
Okay first you should not instanciate the type Car because it is an abstract type (cannot be instanciated). This means that you've "factored" all the code that is common across Audi, Mercedes etc in one class so you wouldn't have to say "An Audi has a model name, a registration plate number etc..." then, again "A Mercedes has a model name, a registration plate number etc..."

Instead, using an abstract Car class, you're basically saying "A Car has a model name, a plate number etc", and Audi and Mercedes are both Cars (they "extend" Car, just like Cow extends Animal).

So you can see that trying to do Car car = new Car() and Audi audi = (Audi)car makes no sense because you're trying to cast an abstract type to a "concrete" type. The correct way to do this is the other way around, eg

Code
Car audi = new Audi(); //an Audi object with the Car type, you have access the Car methods (setColor(), getModelName(), getPlateNumber() etc)
audi.setColor("red");


So your classes should look something like this:

Code
public abstract class Car { // Notice the use of abstract
    private String color;
    public void setColor(String color) {
        this.color = color;
    }
}

public class Audi extends Car { // A concrete implementation of a car
    //code that is specific to the Audi cars goes here
}


Hope it helped


Yea i figured all that out and had to rewrite the code as i had it.

The issue being that i started out with an ArrayList with cars and later on i figured out which kind of cars it was.
My first way of solving this was by taking out the individual Cars, typecasting them into the appropriate brand and then re-inserting them into the array at the spot they already had.

HOWEVER even if this would have worked it's baaad programming, got it sorted out the way you just descriped instead (only issue being it was a far more complex situation than shown here ^^)

Ty for the help though!
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Feb 21 2014 12:45pm
When dealing with polymorphism and inheritance always remember your "is a" relationships. If something extends, ie inherits from, another then it "is a" other thing.

In this example Audi extends Car. So Audi "IS A" Car. But Car "is a" Audi is not always true. All audis can be cast as cars, but not all cars can be cast as Audis.


A square is a rectangle but s rectangle is not always a square. A square is a special type of rectangle.
Go Back To Programming & Development Topic List
Add Reply New Topic New Poll