我正在测试协变返回类型并遇到了这个问题。
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使用的是实际对象而不是引用。
由于
答案 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)
您的问题是正确的,但多态性仅适用于函数。它不适用于变量。在执行变量时它将采用引用类型,而不是引用指向的确切对象类型。您将获得它。