为什么在Java中会发生这种情况?

时间:2018-07-05 09:44:25

标签: java

我想我已经有一段时间了解Java了,我缺乏一些基本概念。这是我要运行的代码:

   class A{
    int x =10;
    void al(){
        System.out.println("From a");
    }
}
class B extends A{
    int x = 20;
    void al(){
        System.out.println("From b");
    }

    public static void main(String args[]){
        A obj = new B();
        B obj1 = new B();
        A obj2 = new A();
        System.out.println(obj.x);
        obj.al();
        System.out.println(obj1.x);
        System.out.println(obj2.x);
    }
}

这是输出:

  10
From b
20
10

当我尝试调用函数 al 时,它将调用 B 类中的函数。在这里发生简单的覆盖。 Obj尝试首先在基类中找到,然后在超类中找到。 现在,当我尝试通过对象 obj 访问“ X”时,它显示为“ 10”。 为什么它不显示“ 20”?

3 个答案:

答案 0 :(得分:4)

您的问题特别是似乎是“为什么System.out.println(obj.x);会打印10张而不是20张?”

obj被声明为A,因此obj.x将始终解析为x中存在的字段A。字段没有dynamic dispatch

最终,您的问题是Java中没有覆盖任何字段。超类中的字段仅获得hidden。当您声明

class A {
    int x = 10;
}
class B extends A{
    int x = 20;
}

并实例化一个B,您返回的对象实际上包含两个整数。它们具有相同的名称的事实基本上是偶然的,并且使得独立地引用它们稍微有些困难,这通常就是为什么您应该选择不同的名称的原因。

答案 1 :(得分:2)

您不能覆盖属性,因为您可以覆盖方法。尽管实例的类型为BAx,并且实例的类型为BAx,Bx是两个不同的属性,并且无论如何都没有关联,但是A.al()被B.al()覆盖了。 >

答案 2 :(得分:1)

实例variables 无法被覆盖。它们是在编译时解析的,而不是 instance方法