Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java继承方法问题_Java_Inheritance_Scjp - Fatal编程技术网

Java继承方法问题

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

在准备SCJP 6考试时,我在一次考试中遇到了这个问题:

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有不同的名称,事情会更容易看到。这是对这个问题的一个非常好的书面回答。肖恩是对的-呼叫超级是这里的关键。这是一个非常好的书面回答这个问题。肖恩是对的-呼叫超级是这里的关键。