Java继承方法问题
在准备SCJP 6考试时,我在一次考试中遇到了这个问题:Java继承方法问题,java,inheritance,scjp,Java,Inheritance,Scjp,在准备SCJP 6考试时,我在一次考试中遇到了这个问题: class A{ private static String staticProperty = " a "; String getStaticProperty() { return staticProperty; } } class B extends A { private static String staticProperty = " b "; public static v
class A{
private static String staticProperty = " a ";
String getStaticProperty() { return staticProperty; }
}
class B extends A {
private static String staticProperty = " b ";
public static void main(String[] args){
new B().go(new A());
}
void go(A t){
String s = t.getStaticProperty() + B.staticProperty + staticProperty + (new B().getStaticProperty());
System.out.println(s);
}
}
输出是什么
这里的输出是a
我完全理解a b,但不理解最后的a。如果您在这种情况下继承了一个方法,B从a继承getStaticProperty,并且该方法从父staticProperty返回一个静态变量,您将在子级中重新定义该静态变量,您将始终使用父静态变量值
顺便说一下,删除静态标识符并使staticField成为类的实例成员会返回相同的结果。将访问修饰符从private修改为public或其他将返回相同的结果。我需要重写getStaticProperty方法以获得我想要看到的内容。new B.getStaticProperty从A调用该方法,该方法返回A的静态属性,因为它的作用域为A。new B.getStaticProperty从A调用该方法,该方法返回A的静态属性,因为它的作用域为A。getStaticProperty是在类a上定义的方法。该方法在类B上不被重写,因此使用来自类a的方法。由于A无法以任何方式“查看”B的静态属性,因此它返回自己的值。getStaticProperty是在类A上定义的方法。该方法在类B上未被重写,因此使用了类A中的方法。因为A不能以任何方式“看到”B的静态属性,所以它返回它自己的值。函数在Java中是虚拟的,但类成员或实例不是静态的。因此,虽然B对staticProperty的定义可能会屏蔽A的定义,但它不会覆盖它
// in B
String fromChild = staticProperty; // == "b"
String fromParent = A.staticProperty; // == "a", was masked but not overridden
要让A访问在B中定义的变量,唯一的方法是在A中定义一个getter函数并在B中重写它,正如您所建议的那样。函数在Java中是虚拟的,但类成员或实例不是静态的。因此,虽然B对staticProperty的定义可能会屏蔽A的定义,但它不会覆盖它
// in B
String fromChild = staticProperty; // == "b"
String fromParent = A.staticProperty; // == "a", was masked but not overridden
要让A访问B中定义的变量,唯一的方法是在A中定义一个getter函数,并按照您的建议在B中重写它。字段访问不受类似方法访问的约束,即不能重写字段。A类中的这一行:
String getStaticProperty() { return staticProperty; }
因此,引用类A中的字段staticProperty。类B的同名字段是无关的,或者更确切地说:它隐藏了超类字段,类B中的所有代码都将使用此字段。在这件事上有这样的说法:
在类中,具有
与超类中的字段同名
隐藏超类的字段,即使
它们的类型不同。在
子类,超类中的字段
不能由其简单
名称相反,字段必须是
通过超级访问,这是
将在下一节中介绍。通常地
说实话,我们不建议躲起来
字段,因为它使代码难以
阅读
字段访问不受类似方法访问的约束,即字段不能被覆盖。A类中的这一行:
String getStaticProperty() { return staticProperty; }
因此,引用类A中的字段staticProperty。类B的同名字段是无关的,或者更确切地说:它隐藏了超类字段,类B中的所有代码都将使用此字段。在这件事上有这样的说法:
在类中,具有
与超类中的字段同名
隐藏超类的字段,即使
它们的类型不同。在
子类,超类中的字段
不能由其简单
名称相反,字段必须是
通过超级访问,这是
将在下一节中介绍。通常地
说实话,我们不建议躲起来
字段,因为它使代码难以
阅读
当考虑像这样的继承问题时,您可能会发现考虑调用newb时会发生什么是很有帮助的。当B的构造函数执行时,它执行的第一个操作是super,因为没有显式调用A的构造函数。此时将创建的实例,并且在该对象中,getStaticProperty方法明确地引用了A的staticProperty。然后,B的构造函数体再次运行,只有在成功执行A的构造函数之后,并且由于它不改变或重写由A的构造函数实例化的getStaticProperty方法,因此它当然也不会改变该方法的行为
这在一开始可能会让人感到困惑,但它是一种有助于思考各种继承问题的含义的方法。在思考像这样的继承问题时,您可能会发现思考调用new B时会发生什么是很有帮助的。当B的构造函数执行时,它执行的第一个操作是super,因为没有显式调用A的构造函数。此时将创建的实例,并且在该对象中,getStaticProperty方法明确地引用了A的staticProperty。然后,B的构造函数体再次运行,只有在成功执行A的构造函数之后,并且它什么也不做 要更改或重写由A的构造函数实例化的getStaticProperty方法,它当然也不会更改该方法的行为
这一点在一开始可能会让人感到困惑,但它是思考各种继承问题的一种有用的方式。因此,即使B从a继承了getStaticProperty方法,结果是,如果B声明了它自己,那么这个继承的方法仍然引用来自超类的属性?我看到了与成员名称的冲突。也许如果B中的staticProperty具有不同的名称,事情会更容易看到。因此,即使B从a继承了getStaticProperty方法,因此,如果B声明了它自己,那么这个继承的方法仍然引用来自超类的属性?我看到了与成员名称的冲突。也许如果B中的staticProperty有不同的名称,事情会更容易看到。这是对这个问题的一个非常好的书面回答。肖恩是对的-呼叫超级是这里的关键。这是一个非常好的书面回答这个问题。肖恩是对的-呼叫超级是这里的关键。