扩展变量和协变返回类型

时间:2011-08-07 09:43:07

标签: java oop inheritance override covariance

我正在测试协变返回类型并遇到了这个问题。

class Vehicle {

    int i = 3;
}
class Car extends Vehicle{

    int i = 5;

    public Car returningCar(){
        System.out.println("Returning Car");
        return new Car();
    }

    public Vehicle returningCarInVehicle(){
        System.out.println("Returning CarInVehicle");
        return new Car();
    }
}

public class ScjpTest{

    public static void main(String[] args){

        Car car = new Car();
        Vehicle vehicleCar = car.returningCar();
        Vehicle vehicleCar2 = car.returningCarInVehicle();

        System.out.println("vehicleCar " + vehicleCar.i);
        System.out.println("vehicleCar2 " + vehicleCar2.i);

    }
}

上面的输出是返回汽车

   Returning 
   CarInVehicle
   vehicleCar 3
   vehicleCar2 3

我不明白为什么输出是3.我希望两个实例中的输出都是5,因为在运行时JVM使用的是实际对象而不是引用。

由于

3 个答案:

答案 0 :(得分:4)

字段不是虚拟/可覆盖/等。它们将根据引用的编译时类型进行解析,在本例中为Vehicle

此代码将打印“vehicleCar2 5”:

System.out.println("vehicleCar2 " + ((Car)vehicleCar2).i);

因为强制转换表达了编译时类型Car

答案 1 :(得分:2)

您需要使用方法来获取您所追求的多态行为(通过将它们设为私有并提供公共setter和getter方法,这也是encapsulate成员变量的最佳实践)

    class Vehicle {

        private int i = 3;

        protected Vehicle(int i) {
            this.i = i;
        }

        public int i() {
            return i;
        }
    }
    class Car extends Vehicle{

        public Car() { 
            super (5);
        }

        public Car returningCar(){
            System.out.println("Returning Car");
            return new Car();
        }

        public Vehicle returningCarInVehicle(){
            System.out.println("Returning CarInVehicle");
            return new Car();
        }
    }

    public static void main(String[] args){

        Car car = new Car();
        Vehicle vehicleCar = car.returningCar();
        Vehicle vehicleCar2 = car.returningCarInVehicle();

        System.out.println("vehicleCar " + vehicleCar.i());
        System.out.println("vehicleCar2 " + vehicleCar2.i());

    }

答案 2 :(得分:2)

您的问题是正确的,但多态性仅适用于函数。它不适用于变量。在执行变量时它将采用引用类型,而不是引用指向的确切对象类型。您将获得它。