Java继承 - 此关键字

时间:2012-12-31 05:08:50

标签: java inheritance override this

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

在以下程序中,为什么'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);
    }
}

3 个答案:

答案 0 :(得分:7)

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

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

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
    }
}

答案 1 :(得分:2)

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

答案 2 :(得分:2)

无法覆盖类变量。

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

在您给出的示例中,通过在类TestChild中声明名为“i”的类变量,您可以隐藏它将从其超类TestParent继承的类变量,并使用相同的名称'一世'。以这种方式隐藏变量不会影响超类TestParent

中类变量'i'的值

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

即可
class TestChild extends TestParent{

    private int i = 200;

    @Override
    public int getI() {
         return this.i;
    }
}