user1947415
user1947415

Reputation: 983

About casting sub-class to super-class in JAVA

public class Car {

    String color;

    public void thisIs(){
        System.out.println("Calling method from Car: the color is " + color);
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

public class BMW extends Car {

    public void thisIs(){
        System.out.println("Calling method from BMW: the color is " + color);
    }
    public Car toCar(){
    Car newCar = new Car();
    newCar.setColor(this.color);
    return newCar;
}

}

public class AbstractTest {

    public static void main(String args[]){
        Car aCar = new Car();
        aCar.setColor("Red");
        aCar.thisIs();

        BMW aBMW = new BMW();
        aBMW.setColor("Black");
        aBMW.thisIs();

        //Car aaCar = new Car();
        //aaCar = (Car)aBMW;
        //aaCar.thisIs();

            Car aaCar = aBMW.toCar();
    aaCar.thisIs();
    }
}

I expect the result to be:

Calling method from Car: the color is Red

Calling method from BMW: the color is Black

Calling method from Car: the color is Black

But, the result I got is:

Calling method from Car: the color is Red

Calling method from BMW: the color is Black

Calling method from BMW: the color is Black

Where am I wrong? And how can I use the method from the super class to get the data in a subclass object? I can write a toCar() method in BMW class to do this. But, why casting doesn't work? Thanks ahead!

OK! Thank you!

I got why casting doesn't work.

So, I add a method in BMW toCar() to get the result I want.

Upvotes: 3

Views: 22235

Answers (5)

me_digvijay
me_digvijay

Reputation: 5492

Well You don't need to explicitly cast the BMW object to a Car type, because a BMW object is a subclass of Car and a Car can be of any type (a BMW or anything). So when you assign the BMW object to a car the implicit casting is done by the compiler. In your case you are explicitly asking the compiler to cast the BMW object to car type.

Also this implicit casting doesn't mean that the BMW object will loose its thisIs() method or any other property.

Upvotes: 0

codeMan
codeMan

Reputation: 5758

This is because of the runtime polymorphism. The last statement is because even if you have a car reference pointing to the BMW object(by casting you are not modifying the nature of the object! BMW will still be a BMW it does not become Car object!), Ultimately its the BMW's thisIs() method that will be called! This is know as Dynamic Method Dispatch

Upvotes: 2

arcy
arcy

Reputation: 13123

Casting the object does not change the nature of the object. It is still a BMW object; casting just tells the compiler to treat it as though it were a Car object.

As long as we're on the subject of inheritance: there is NO need to put either the color variable or the get/setColor methods into both the super and subclass. Putting them in the car class means they are available in any subclass; they are superfluous and a bit confusing in the subclass. I would take them out entirely.

Upvotes: 14

Usman Saleem
Usman Saleem

Reputation: 1655

Consider following code:

public void someMethod(Car c) {
  c.thisIs(); 
}

'c' can hold reference of all subclasses. Whichever reference is hold by 'c', that method will be called. Its also called runtime polymorphism.

Upvotes: -1

Ben Zotto
Ben Zotto

Reputation: 71008

The BMW is still a BMW even if you call it a car.

The cast doesn't change what the object is. It just tells the compiler how you intend to treat it. You created a BMW, and it's still one when you call its thisIs method.

Upvotes: 1

Related Questions