Java 中的字段不存在多态性。然而,还有继承。您实际上所做的就是在 Rectangle 类中创建两个具有相同名称的字段。该字段的名称实际上是:
public class Rectangle {
public int Shape.x;
public int Rectangle.x;
}
上面并不代表有效的 Java,它只是说明了字段在类中的范围如何
在 Rectangle 类的整个范围内,同名的超类字段是hidden。所以任何时候你引用简单的名字x
,或范围名称this.x
,在类中,您指的是定义在Rectangle
。您实际上也可以使用作用域名称访问超类字段super.x
.
现在,从类外部来看,访问哪个字段的规则略有不同。范围将由compile引用字段的类的时间类型。所以在你的代码中:
Shape s = new Shape();
Rectangle r = new Rectangle();
s = r;
System.out.println(s.x);
输出是0
因为编译时类型s
is Shape
(not Rectangle
)。当您执行以下操作时,您可以观察到此行为的变化:
Shape s = new Shape();
Rectangle r = new Rectangle();
s = r;
System.out.println(((Rectangle)s).x);
急!你的输出现在是1
,因为编译器发现您已将字段访问范围限制为Rectangle
.
压缩可见性规则:
您可以阅读有关实例变量隐藏的更多信息JLS,第 8.3.3.2 节 http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.3.3.2