我只是在玩static
和继承,看看能做什么和不能做什么。我以前读过,静态方法不能被覆盖,它们可以简单地隐藏起来。这就是为什么我试图看看什么适用于静态成员。这是一些简单的测试代码:
public class ParentClass {
public static String x;
{ x = "In ParentClass"; }
}
public class ChildClass extends ParentClass {
{ x = "In ChildClass"; }
}
现在当我打印从对象调用的x时,一切都按预期进行:
ParentClass parentClassReference = new ParentClass();
System.out.println(parentClassReference.x); // prints: "In ParentClass"
parentClassReference = new ChildClass();
System.out.println(parentClassReference.x); // prints: "In ChildClass"
甚至可以从子类对象中调用x:
ChildClass childClassReference = new ChildClass();
System.out.println(childClassReference.x); // prints: "In ChildClass"
现在,当我调用静态成员时,就像它应该完成一样,它变得很奇怪:
System.out.println(ChildClass.x); // prints: "In ChildClass" (Ok, so far.)
System.out.println(ParentClass.x); // prints: "In ChildClass" (This is unexpected.)
我对此行为没有任何解释。在Overriding vs. Hiding (Code Ranch)的上下文中,通过对象的调用似乎不太可能按预期工作,但通过类名调用应该。
我很困惑。谁可以帮忙?
答案 0 :(得分:4)
您的代码非常很奇怪...但结果与我期望的完全一样。
你需要了解三件事:
x
变量。无论您将其引用为ChildClass.x
还是ParentClass.x
,它都是相同的变量childClassReference.x
相当于ChildClass.x
,实际上编译为ParentClass.x
。好的IDE会警告你这类事情 - 它会产生令人困惑的代码。您编写的设置值x
的代码仅基于构造函数调用执行。基本上它相当于:
public class ParentClass {
public static String x;
public ParentClass() {
x = "In ParentClass";
}
}
public class ChildClass extends ParentClass {
public ChildClass() {
x = "In ChildClass";
}
}
从根本上说,您不应该尝试通过静态成员实现任何类型的多态性。它不起作用,并试图伪造它不会愉快地结束。