1

質問があり、以下が私のコードです。

class A
{
    int i=10;
    public void m1() {
        System.out.println("I am in class A");
    }    
}

class B extends  A 
{    
    public void m1() { 
        System.out.println("I am in class B"); 
    }       
}

class main2 extends A 
{       
    public static void main(String...a) {
        A a1= new B();
        a1.m1();    
    }
}

今私の質問です。親クラス A の変数「i」を取得しても問題ありませんが、取得しているメソッドもクラス A のものです。クラス A のメソッドをオーバーライドするため、クラス B のメソッドを取得していますか?

4

3 に答える 3

1

Java では、任意の派生クラス オブジェクトを基本クラス変数に割り当てることができます。たとえば、クラス B を派生させた A という名前のクラスがある場合、次のようにできます。

A a1 = new B();

左側の変数は型 A ですが、右側のオブジェクトは型 B です。左側の変数が B の基底クラスである限り、それを行うことができます。このような割り当てを行うことができると、いわゆる「ポリモーフィック動作」が設定されます。B クラスに A クラスのメソッドと同じメソッドがある場合、B クラスのメソッドのバージョンが呼び出されます。たとえば、両方のクラスで m1() というメソッドが定義されている場合、次のようにします。

a1.m1();

B クラスの m1() のバージョンが呼び出されます。A 変数型を使用してメソッド m1() を呼び出している場合でも、A クラスのバージョンの m1() は実行されません。代わりに、実行されるのは B クラスの m1() のバージョンです。A 変数に割り当てられたオブジェクトの型によって、呼び出されるメソッドが決まります。

そのため、コンパイラがプログラムをスキャンし、次のようなステートメントを確認すると:

a1.m1();

a1 が型 A であることは認識していますが、コンパイラは、a1 が A から派生した任意のクラスへの参照になる可能性があることも認識しています。したがって、コンパイラは、そのステートメントが呼び出している m1() のバージョンを認識していません。課題までではありません:

A a1 = new B();

m1() のバージョンが決定されるように実行されます。割り当ては実行時まで行われないため、正しいバージョンの m1() が認識されるのは実行時までではありません。これは「<strong>ダイナミック バインディング」または「<strong>遅延バインディング」として知られています。実行時にプログラムが何らかの操作を実行するまで、メソッドの正しいバージョンを判断することはできません。Java では、継承のほとんどの用途に動的バインディングが含まれます。

于 2012-05-05T07:56:07.110 に答える