Java 扩展变量和协变返回类型
我在测试协变返回类型时遇到了这个问题Java 扩展变量和协变返回类型,java,oop,inheritance,overriding,covariance,Java,Oop,Inheritance,Overriding,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(){
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使用的是实际对象而不是引用
谢谢字段不是虚拟的/可重写的/etc。它们将根据参考的编译时类型进行解析,在本例中为
车辆
此代码将打印“vehicleCar2 5”:
由于强制转换使编译时类型的表达式
Car
字段不是虚拟的/可重写的/etc。它们将根据引用的编译时类型进行解析,在本例中为Vehicle
此代码将打印“vehicleCar2 5”:
由于cast生成编译时类型的表达式
Car
,您需要使用方法来获得您所追求的多态行为(将成员变量设置为私有并提供公共setter和getter方法,这也是成员变量的最佳实践)
您需要使用方法来获得所追求的多态行为(将成员变量设置为私有并提供公共setter和getter方法,这也是成员变量的最佳实践)
您的问题是正确的,但多态性仅适用于函数。它对变量不起作用。执行变量时,它将采用引用类型,而不是引用所指向的确切对象类型。希望您能得到它。您的问题是正确的,但多态性仅适用于函数。它对变量不起作用。执行变量时,它将采用引用类型,而不是引用所指向的确切对象类型。希望您能得到它。因此字段永远不会被覆盖?@ziggy Right。它们可以被有效地隐藏,但永远不会被覆盖。我最近发现静态方法也存在类似的情况。我猜当涉及重写时,字段也被视为与静态方法相同。@Ziggy是的,静态方法也不可用于重写。所以字段永远不会被重写?@Ziggy是的。它们可以被有效地隐藏,但永远不会被覆盖。我最近发现静态方法也存在类似的情况。我猜当涉及重写时,字段也被视为与静态方法相同。@Ziggy是的,静态方法也不可用于重写。这与协变返回类型有什么关系?我刚刚发现了一些关于Java的东西。在其他编程语言中,“inti=5;”将被标记为“复制”标识符。它与协变返回类型有什么关系?我刚刚发现了一些关于Java的东西。在其他编程语言中,“inti=5;”将被标记为“复制”标识符。
System.out.println("vehicleCar2 " + ((Car)vehicleCar2).i);
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());
}