以下代码段将输出显示为
Sup.field = 0,Sup.getField()= 1
我不明白为什么Sup.getField()没有得到0?
class Super {
public int field = 0;
public int getField(){return field;}
}
class Sub extends Super {
public int field = 1;
public int getField() {return field;}
public int get SuperField() { return super.field;}
}
public class FieldAccess{
public static void main(String[] args){
Super Sup = new Sub();
System.out.println("Sup.field ="+Sup.field + ",Sup.getField()"+Sup.getField());
}
}
答案 0 :(得分:3)
默认情况下,java中的所有方法都是虚拟的(c#term)或多态的,这就是你所看到的(类字段不是)。
当您致电sup.field
时,它会访问课程field
中的字段Super
,但是当您致电getField()
时,它会调用课程{{1}中的getField()
方法因为实例的类型为Sub
。
This page有一个很好的定义和一些多态的例子。
答案 1 :(得分:3)
不会覆盖实例变量..它们只是隐藏。参考super.field
指的是基于引用的超类中的实际字段。
重写方法,并在运行时根据对象类型进行调用。
答案 2 :(得分:0)
这是因为,
Super Sup = new Sub();
这意味着该对象包含派生类对象的实例。这意味着,在对象存储器中,字段的值为1而不是0。
所以,当你运行
Sup.getfield()
它运行派生类的方法,该类驻留在被标记为超类的内存的内存中。
所以,它的不同之处和看起来是什么样的。
答案 3 :(得分:0)
您目击的是方法重写的效果(不要与方法重载混淆)。
即使引用类型是Super()类型,实际的调用方法在程序执行时解析(运行时多态),并且因为子类重写了getField()方法,所以调用它然后返回子类型中的值。如果在两种情况下都需要0,请将实例化更改为Super Sup = new Sub();