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のスーパークラスであるため、これを実行できます)。その後、コンパイル時にコードが満たされるため、エラーは発生しません。実行時に、プログラムは「hello()」を探します。ここで、「obj」は、定義されている場所ではなく、参照しています。ただし、「numt」の場合は逆になります。なんでそうなの?そして、私の上記の理解は正しいですか?そうでない場合は修正してください。

どうもありがとう!私はそれが初心者の質問であることを知っています、私はOOPに非常に新しいです。

4

4 に答える 4

4

メソッドを呼び出すと、ポリモーフィズムのため、参照型ではなく、インスタンス内のメソッドが呼び出されます。ここでは、参照がタイプA2であるにもかかわらず、オブジェクトはC2であるため、C2のメソッドが呼び出されます。

変数にアクセスすると、ポリモーフィズムはフィールドに適用されないため、オブジェクトタイプよりも参照タイプになります。そのため、他のクラスがこれらの変数に直接アクセスできないように、変数をプライベートにすることは常に優れた設計です。

于 2012-09-14T20:45:21.917 に答える
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で印刷されるので:C2からこんにちは

2番目のケースでは、インスタンス変数に新しい値を割り当てなかったため、次のint numtように出力されます:111。varに新しい値を割り当てます。numtこれを行う:

obj.numt=666;
于 2012-09-14T20:52:17.583 に答える
0

メソッドをオーバーライドする方法でフィールドをオーバーライドすることはできません。これらはポリモーフィックではないため、フィールドにアクセスしているタイプに指定された値を常に取得します。たとえば、「最終的な」メソッドと比較できます。これらのメソッドは同じように動作します。

于 2012-09-14T21:14:54.177 に答える