Javainheritance – 此关键字

我在网上搜索了类似的问题,但找不到它。 所以,发帖在这里。

在以下程序中,为什么“i”的值打印为100?

AFAIK’this’指的是当前的对象; 在这种情况下,它是’TestChild’,类名也正确打印。 但为什么实例变量的值不是200?

public class TestParentChild { public static void main(String[] args) { new TestChild().printName(); } } class TestChild extends TestParent{ public int i = 200; } class TestParent{ public int i = 100; public void printName(){ System.err.println(this.getClass().getName()); System.err.println(this.i); //Shouldn't this print 200 } } 

而且以下的输出正如我所期望的那样。 当我从Parent类调用“ this.test() ”时,将调用子类方法。

 public class TestParentChild { public static void main(String[] args) { new TestChild().printName(); } } class TestChild extends TestParent{ public int i = 200; public void test(){ System.err.println("Child Class : "+i); } } class TestParent{ public int i = 100; public void printName(){ System.err.println(this.getClass().getName()); System.err.println(this.i); //Shouldn't this print 200 this.test(); } public void test(){ System.err.println("Parent Class : "+i); } } 

Java没有虚拟字段,因此printNamei字段始终引用TestParent.i而不是任何后代子代。

通过Javainheritance的多态性只发生在方法中,所以如果你想要你正在描述的行为那么你需要这样:

 class TestChild extends TestParent{ private int i = 200; @Override public int getI() { return this.i; } } class TestParent{ private int i = 100; public int getI() { return this.i; } public void printName(){ System.err.println( this.getClass().getName() ); System.err.println( this.getI() ); // this will print 200 } } 

因为Java中的字段不是inheritance的。 使用您的声明,您已经有效地声明了两个名为i 不同字段,而TestChild实例将同时具有这两个字段。 编译TestParent ,在其方法中对i引用将始终引用TestParent.i

无法覆盖类变量。

您不会在Java中覆盖类变量,而是隐藏它们。 覆盖是例如方法和隐藏不同于覆盖。

在您给出的示例中,通过在类TestChild声明名为“i”的类变量,您可以隐藏它将从其超类TestParentinheritance的类变量,其名称为“i”。 以这种方式隐藏变量不会影响超类TestParent类变量“i”的TestParent

要获得所需的行为,您可以覆盖getI()方法

 class TestChild extends TestParent{ private int i = 200; @Override public int getI() { return this.i; } }