我对Java中的variable hiding and method overriding和virtual method calling有所了解。 我的问题是,为什么变量隐藏无法在继承的方法中生效?这是否意味着我们必须重写在每个子类中访问这些变量的方法?
抽象类
public abstract class ClassA{
protected int i = 0;
public void printOurStuff(){
System.out.println(i);
}
public void printMyStuff(){
System.out.println(this.i);
}
public void printSomeStuff(String s){
System.out.println(s);
}
}
具体课程
public class ClassB extends ClassA{
protected int i = 1;
public static main(String[] args){
ClassB b = new ClassB();
b.printOurStuff();
b.printMyStuff();
b.printSomeStuff(b.i);
}
}
结果
0 0 1
编辑-将字段的访问修饰符从专用更改为受保护和添加的方法printOurStuff
答案 0 :(得分:2)
声明诸如
之类的私有字段时 private int i = 0;
这意味着只有这个具体的类才能访问该变量。该字段不适用于子类。如果希望此字段可用于子类,则应将其设置为protected
:
protected int i = 0;
要覆盖此字段的值,可以使用静态块,例如:
public class ClassB extends ClassA {
{
i = 1;
}
}
或在构造函数中分配新值:
public class ClassB extends ClassA {
public ClassB() {
i = 1;
}
}
以您的示例为例,如果使用调试器检查ClassB
对象,则会发现实际上有两个i
字段:一个用于ClassA
,一个用于{{1 }}。
更新:
对于ClassB
变量为i
的情况:
仔细查看您的类定义。
您不能不同意两次声明 protected
字段:i
和ClassA
。 JVM将遵守此声明并遵循您的指示。如果该字段是ClassB
或什至protected
,则您仍然有两个字段。您不能像覆盖方法一样覆盖它们。当访问public
之类的字段时,实际上是在访问与范围最接近的字段。对于i = ...
,它是其字段ClassB
,而不是其超类i
的字段。
此外,您仍然可以按如下方式访问超类的字段:
ClassA
super.i = ...
是对超类的引用。