【问题标题】:Why this is happening in Java? [duplicate]为什么在 Java 中会发生这种情况? [复制]
【发布时间】:2018-07-05 09:44:25
【问题描述】:

我已经了解 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”?

【问题讨论】:

  • 因为 A.x 和 B.x 是不同的野兽,因为 B 重新声明 x
  • 您需要参考继承中的向上转换和向下转换等概念,这就是这里发生的事情
  • Java 中不存在属性覆盖

标签: java


【解决方案1】:

具体来说,您的问题似乎是“为什么 System.out.println(obj.x); 打印 10 而不是 20?”

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

最终,您的问题是 Java 中没有字段覆盖。超类中的字段只是得到hidden。当你声明

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

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

【讨论】:

    【解决方案2】:

    你不能覆盖属性,因为你可以覆盖方法。 “obj”被声明为 A 类型的对象,尽管实例是 B 类型。A.x 和 B.x 是两个不同的属性,并且没有任何关系,尽管 A.al() 被 B.al() 覆盖。

    【讨论】:

      【解决方案3】:

      实例variables不能被覆盖。它们在编译时解决,而不是实例方法

      【讨论】:

        猜你喜欢
        • 2013-12-09
        • 1970-01-01
        • 1970-01-01
        • 2013-08-02
        • 2018-12-19
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        相关资源
        最近更新 更多