Search code examples
javainheritancecasting

Narrowing Casting problem spoted by Intellij IDEA


I'm trying to create a "Truck" using downcasting from the parent class (Truck extends Car)

private Truck truck;

public void createTruck() {
    Car basicCar = new Car();
    this.truck = (Truck) basicCar;
}

But for some reason Intellij IDEA spots a problem

Casting 'basicCar' to 'Truck' will produce 'ClassCastException'for any non-null value

What have I done wrong?


Solution

  • new Car will always be a Car instance. Unless Truck, Sedan, and Cabriolet are all interfaces, Car cannot be all of them at the same time (and it would be weird to have Car implements Truck, Sedan, Cabriolet; that doesn't really make sense).

    And why are you casting if you are only returning a Car from your method anyway? Effectively you execute return (Car)(Truck)new Car(…);

    You cannot cast objects of the base class to a child class, because the base class doesn't have all the information required to represent instances of the child class.

    Consider the following example:

    class Car {
      int wheels;
      Car(int wheels) { this.wheels = wheels; }
    }
    class Truck extends Car {
      int weight;
      Truck(int wheels, int weight) {
        super(wheels);
        this.weight = weight;
      }
    }
    
    class Program {
      public static void main() {
        Car car = new Car(4);
        Truck truck = (Truck)car;
        // what's the weight of the truck? impossible to know, because a Car is not a Truck
      }
    }
    

    The above doesn't work, but the following does:

    class Program {
      public static void main() {
        Car car = new Truck(4, 1000);
        Truck truck = (Truck)car;
        System.out.println(truck.weight);
      }
    }