谁能解释一下这里发生了什么以及为什么?
class Base{
private float f = 1.0f;
void setF(float f1){ this.f = f1; }
float getF() {return f;}
public void xx(){}
}
class Base2 extends Base{
private float f = 2.0f;
public void xx(){
System.out.println(super.getF()+" "+this.getF());
}
//float getF() {return f;} //1
//void setF(float f1){ this.f = f1; } //2
public static void main(String[]args){
Base b=new Base2();
b.setF(3);
b.xx();
System.out.println(b.getF());
System.out.println(((Base)b).getF());
}
}
这段代码的输出将是 3,3,3 。
如果我用getter取消第1行注释,输出将是 3,2,2 。
如果我用setter取消第2行注释,输出将是1 1,1,1 。
如果我取消第1行和第2行(带有setter和getter)的注释,输出将是 1,3,3 。
//default output: 3 3, 3, 3
//with getter: 3 2, 2, 2
//with setter: 1 1, 1, 1
//with getter and setter: 1 3, 3, 3
如果用子类中的代码重写父类中的方法,则该重写方法不能访问私有成员变量,即使父类中被重写的方法可以访问。子类中的重写方法可以调用父类中的重写方法。
所以,这是解释情况#4的getter和setter,只能访问Base2成员变量
你得到3 3 3 3
,因为set/get方法修改了Base.f
变量:
你得到3 2 2 2
是因为设置了Base.f
变量的变化值,但是get方法得到了Base2.f
变量的值。
你得到1 1 1 1
是因为set方法改变了Base2.f
变量的值,但是get方法得到了Base.f
变量的值。
你得到1 3 3 3
,因为super.getF()
返回Base.f
变量的值,但其他get方法返回Base2.f
变量的值。还有Base2.f
变量的set方法更改值
让我们从一些背景开始。
在继承Java教程中说明:
超类中的私有成员
子类不继承父类的私有成员。但是,如果超类有public或protected方法访问它的私有字段,这些字段也可以被子类使用。
在多态性一章中说明:
Java虚拟机(JVM)调用适当的方法在每个变量中引用的对象。它不调用方法,该方法由变量类型定义。这种行为是称为虚拟方法调用并演示一个方面Java语言中重要的多态性特性
最后,在同一教程的隐藏字段章节中说明:
在类中,与类中的字段名称相同的字段父类隐藏父类的字段,即使它们的类型是不同。在子类中,超类中的字段不能为通过其简单的名称来引用。相反,必须访问该字段通过super,这将在下一节中介绍。一般总的来说,我们不建议隐藏字段,因为这会使代码变得困难阅读。
因此,子类无法直接访问超类的私有成员。但是,它们仍然存在,并且可以使用非私有访问器/mutator访问或修改。
现在回到问题本身。
在您的第一个示例中,您既没有重写访问器也没有重写mutator—您只是一直调用继承的那一个。它们返回并修改Base的f的值。为什么继承的accessor/mutator不返回/修改Base2的f的值?因为即使Base的f不是私有的,它也不会被覆盖,而只是被隐藏。
在第二个示例中,您重写了访问器。这是开始涉及多态性的地方。这个简短的回答可能有助于理解它。调用b.setF(3)
时,设置Base的f的值。但是,当您调用getF()
时,您将获得Base2的f的值,除非您使用关键字super调用它。请注意,在上次调用中,System.out.println(((Base)b).getF())
转换为Base没有任何作用,因为b已经声明为Base。如果不使用super,就不能调用父类的重写方法(正如您已经知道的,只有实例方法可以被重写)。
在第三个示例中,重写了该mutator。情况与你的第二个例子相反。调用b.setF(3)
时,设置Base2的f的值。但是你总是从getter中得到f (Base),因为getter没有被重写。因此,对getF()
的所有4次调用都返回Base的f的初始值。
在上一个示例中,重写了访问器和mutator。因此,它们对Base2的f进行操作。唯一返回Basef的初始值的调用显然是super.getF()
。
这肯定不是一个完美的解释,但我希望它能帮助。