1
class A2 {
    int numt=111; 
  void hello() {

    System.out.println("Hello from A2");
  }
}

class B2 extends A2 {
  void hello() {
    System.out.println("Hello from B2");
  }
}

class C2 extends B2 {
  int numt=666;  
  void hello() {
    System.out.println("Hello from C2");
  }


}

class MethodOverriding2 {
  public static void main(String args[]) {
    A2 obj = new C2();
    obj.hello();
    System.out.println("Num is : " + obj.numt);
  }
}

所以基本上这里的输出是

Hello from C2
Num is : 111

为什么它从 C2 运行 hello() 而从 A2 运行 numt?

据我了解,我将 A2 继承到 B2 中,并将 C2 继承到 B2 中。然后在我的主体中,我正在创建一个引用 C2 的 A2 类的对象(它可以这样做,因为 A2 是 C2 的超类)。然后在编译时没有错误,因为代码得到满足。在运行时,程序会在 'obj' 所指的地方而不是定义的地方查找 'hello()'。但它对“numt”却相反。为什么会这样?我的上述理解正确吗?如果不是,请更正。

非常感谢!我知道这是一个新手问题,我对 OOP 很陌生。

4

4 回答 4

4

当您调用方法时,将调用实例中的方法,而不是由于多态性而在引用类型上。即使引用是 A2 类型,这里您的对象也是 C2,因此将调用 C2 中的方法。

当您访问变量时,它是引用类型而不是对象类型,因为多态性不适用于字段。这就是为什么将变量设为私有以使其他类无法直接访问这些变量总是好的设计。

于 2012-09-14T20:45:21.917 回答
0

您不能以覆盖方法的方式覆盖字段。它们不是多态的,因此您始终会获得为您访问字段的类型指定的值。例如,您可以将其与“最终”方法进行比较,它们的行为方式相似。

于 2012-09-14T21:14:54.177 回答
0

实际上在java中,成员变量不是多态的。所以如果你使用obj.numt,就不会出现编译错误。但是如果你的 obj 是 的引用B2,那么你会得到编译器错误。

在方法的情况下,它们是多态的。因此,如果它是 的对象A2A2.hello()将被调用。如果它是 的对象B2B2.hello()将被调用。情况相同C2

class MethodOverriding2 {
  public static void main(String args[]) {
    // class member variables are not polymorphic(i.e. they are not inherited)
    A2 obj = new C2(); // obj is of type A2, so obj.numt would print 111
    B2 obj1 = new C2(); // obj1 is of type B2, so obj1.numt would give compiler error.
    C2 obj2 = new C2(); // obj2 is of type C2, so obj2.numt would print 666
    obj.hello(); // would call C2.hello() as obj points to object of C2

    A2 obj3 = new B2(); // obj3 is of type A2 which points to object of B2
    obj.hello(); // this would call B2.hello()
  }
}
于 2012-09-14T20:50:53.043 回答
0

在第一种情况下,您覆盖了方法 hello(); 在 C2 中打印:Hello from C2

在第二种情况下,您没有为实例变量分配任何新值,int numt因此它打印:111。为 var 分配新值。千万不要这样做:

obj.numt=666;
于 2012-09-14T20:52:17.583 回答