Расширяющиеся переменные и ковариантные типы возврата - PullRequest
1 голос
/ 07 августа 2011

Я тестировал ковариантные типы возвращаемых данных и столкнулся с этой проблемой.

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 ]

4 голосов
/ 07 августа 2011

Поля не являются виртуальными / переопределяемыми / и т.д.Они будут разрешены в соответствии с типом ссылки во время компиляции, который в данном случае будет Vehicle.

. Этот код будет печатать «vehicleCar2 5»:

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

, так какcast делает выражение типа времени компиляции Car.

2 голосов
/ 07 августа 2011

Ваш вопрос правильный, но полиморфизм работает только для функций.Это не будет работать для переменной.При выполнении переменной будет использоваться ссылочный тип, а не тот тип объекта, на который указывает ссылка. Надеюсь, вы его получите.

2 голосов
/ 07 августа 2011

Вам нужно использовать методы, чтобы получить полиморфное поведение, к которому вы стремитесь (также рекомендуется инкапсулировать переменные-члены, делая их закрытыми и предоставляя общедоступные методы setter и getter)

    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());

    }
...