构造函数和隐藏Java中的字段

时间:2014-09-12 04:51:22

标签: java inheritance binding constructor typing

我正在做这个学校的练习,我无法理解为什么以下两个案例会有不同的结果。有人可以解释为什么在第一种情况下,{A}的int x是100? A中的int x是否在A中隐藏了int x?我也在代码中评论了我的问题。非常感谢!

class A {  // Case 1 
  public int x = 1;
  public String k() { return "A" + this.x; }
 }
class B extends A {
   public int x = 10;
}
class C extends B {
  public int x = 100;
  public String k() { return "C" + this.x; }
}
class TestABC {
  public static void main(String[] args) {
    A a1 = new C();
    C c1 = new C();
 } 
}
System.out.println(a1.x +"," + c1.x);// It prints out 1, 100.
   //However I thought it'd print out 100, 100, as the int x in C shadows int x in A. 

另一个案例是

class A1 { //case 2
  int x=10;
  public void method() {
  System.out.print("A:" + this.x + " ");
  }
}
class B1 extends A1 {
  int x=20;
public void method() {
  System.out.print("B:" + this.x + " ");
}
public static void main(String args[]) {
   A1 s = new B1();
   s.method();// It prints out B: 20. 
   //What's the difference between this one and a1.x in the previous example? 
   //Why it prints out the subclass but in the previous code a1.x prints out the parent class?
   }
} 

2 个答案:

答案 0 :(得分:1)

第一个案例打印出1, 100,因为它获得了 VARIABLE 的值 类似的东西:

Get the value of x in A and get the value of x in C

覆盖只发生在 METHODS 而不是VARIABLES。 这就是为什么在第二种情况下它调用B1内的方法而不是A1

这称为运行时多态性


编辑2:

让我进一步解释一下:

当我们在运行时调用方法时,JVM不会查看引用变量的类型,而是查看对象&# 39; s类型并运行该方法。

但是使用变量,反之亦然,而不是查看对象的类型,JVM会查看引用变量的类型,并获取该变量

给出以下示例:

class Animal {

    String whatAmI = "An Animal";

    public void sayHi() {
        System.out.println("Hi from Animal");
    }
}

class Dog extends Animal {

    String whatAmI = "A Dog";

    public void sayHi() {
        System.out.println("Hi from Dog");
    }
}

示例运行:

//Reference variable type               //Object type
Animal              anAnimal            = new Animal();
Dog                 aDog                = new Dog();
Animal              anotherDog          = new Dog();

anAnimal.sayHi();       //Hi from Animal
aDog.sayHi();           //Hi from Dog
anotherDog.sayHi();     //Hi from Dog

我们得到这些输出是因为JVM在Object的类型上调用了sayHi()方法而不是Reference变量的类型。

但事实是,它对变量的作用并不相同。 如果我们尝试这样的话:

System.out.println(anAnimal.whatAmI);       //An Animal
System.out.println(aDog.whatAmI);           //A Dog
System.out.println(anotherDog.whatAmI);     //An Animal

我们有这些输出,因为JVM从Reference变量的类型中获取whatAmI变量。

记住这一点的技巧是关注相等(=)符号

  • 调用方法时,调用右侧的方法 等于(=)符号。
  • 获取变量时,请在左侧获取变量 等号(=)的一面。

答案 1 :(得分:1)

是..这是运行时多态或覆盖。

案例1:A =新C(); 案例2:C c = new C();

多态性规则:

                                          Variable            Method          Static Method
Reference of Superclass(Case 1)             Super               Sub               Super
Reference of Subclass(Case 2)                Sub                Sub                Sub

这些是多态的规则。因此,如果您创建这些类型的任何成员变量,您将始终以此格式查看结果。

因此你看到的结果。