Java中class属性的值

时间:2014-03-06 16:26:28

标签: java oop variables local override

我不明白它究竟是如何运作的。

我们有两个A类和B类.B类扩展A. A类具有x属性,以及修改该属性的测试方法。 B类具有x属性,以及修改该属性的测试方法。

public class A {

    int x;

    public void test() {
         this.x = 1;
        System.out.println("A" + getX());
    }
    int getX() {return x;}
}

public class B extends A {

    int x;

    public void test() {
        this.x = 2;
        System.out.println("B" + getX());
    }
    int getX() {return x;}

}

public class Main {

    public static void main(String[] args) {

        A a = new A();
        a.test();
        System.out.println(a.getX());

        System.out.println("point 1");
        a = new B();
        a.test();
        System.out.println(a.x);
       }
}

输出:

 A1
 1
 point 1
 B2
 0

我对最后一行输出的预测是2,但是为0.为什么是0?

4 个答案:

答案 0 :(得分:5)

让我们理解这些代码:

a = new B();
a.test();
System.out.println(a.x);
  • 您创建了B的新对象。它会重新初始化变量 - A.x = 0B.x = 0
  • 然后你调用a.test(),它将调用类test()中的重写方法B,该方法会使用B.x2设置为this.x = 2; }。请注意,A.x仍为0
  • 然后,您访问a.x,该x将访问课程A中的字段x。这些字段不是多态的。您不会覆盖字段,但隐藏它们。 B中的变量x隐藏了A中的变量{{1}}。

答案 1 :(得分:2)

如果A和B都有一个名为x的成员,B中的成员将阻止访问从A继承的成员。从B中删除int x;声明,或明确使用super.x,如果你想要引用父类中的那个。

答案 2 :(得分:2)

从头开始。

写作时

A a;

你对JVM说请在内存中保留一个适合A的地址。

之后

a = new A();

您对JVM说,创建一个A类的新对象,并在a

下将地址保存到它

当你这样做时;

a.test();

你对JVM说,转到内存地址a,然后从对象调用方法test()

接下来你要做的是:

a = new B();

您对JVM说,创建一个B类的新对象,并在a下将地址保存到它。这里没有错误,因为B适合A,因为是子类。

(你松开了与A类对象的连接,你将它改为B)。

下一步操作是

a.test();

您也知道这一点,但这次在地址a下是类B的实例。这次JVM搜索B类中的方法,如果不喜欢那么将在A类中搜索。

答案 3 :(得分:1)

我认为你应该首先从继承/多态> 概念开始。 但要说清楚:你有一个对象“a”,它被声明为类型“A”。现在,当您调用方法测试(在这种情况下在B内部覆盖)时,JVM会调用 实际对象 方法。因此,在“point 1”之前 a.test调用A的测试方法,在“point1”之后调用B的测试方法。 问题是此功能(称为多态)仅适用于方法。当您调用实例变量(作为a.x)时,JVM会调用 声明的对象 变量。在这种情况下是A.如果您先进行演员表,您将获得正确的价值:((B)a).x 注意,实际和声明对象之间的区别是基于“new”运算符之后的类型(如new B())和对象声明中的类型