方法覆盖 Vs class java 中的变量覆盖

method overriding Vs class variable overriding in java

我只是在尝试一些示例代码来检查 class 变量在 Java 中的覆盖行为。下面是代码:

class A{
  int i=0;

  void sayHi(){
    System.out.println("Hi From A");
  }
}

 class B extends A{
  int i=2;

  void sayHi(){
    System.out.println("Hi From B");
  }
}


public class HelloWorld {
 public static void main(String[] args) {
    A a= new B();
    System.out.println("i->"+a.i); // this prints 0, which is from A
    System.out.println("i->"+((B)a).i); // this prints 2, which is from B
    a.sayHi(); //  method from B gets called since object is of type B
  }
}

我无法理解下面这两行发生了什么

System.out.println("i->"+a.i); // this prints 0, which is from A
System.out.println("i->"+((B)a).i); // this prints 2, which is from B

为什么即使对象是 B 类型,a.i 也会打印 0?为什么它在转换为 B 后打印 2

i 不是方法 - 它是数据成员。数据成员不覆盖,它们隐藏。因此,即使您的实例是 B,它也有两个数据成员 - 来自 Ai 和来自 Bi。当您通过 A 引用引用它时,您将获得前者,而当您使用 B 引用(例如,通过显式转换它)时,您将获得后者。

另一方面,

实例方法的行为不同。无论引用的类型如何,由于实例是 B 实例,您将获得多态行为并打印字符串 "Hi From B"

即使A被初始化为new B(),变量也是一个A,如果你说

B a = new B();

你不会有那个问题。