0

だから、私はこれを持っています:

public class A {

    public int a = 0;
    public void m(){
        System.out.println("A"+a);
    }
}

この:

public class B extends A {

    public int a = 5 ;
    public void m (){
        System.out.println("B"+a);
    }
    public static void main(String[] args) {
        A oa = new A();
        B ob = new B();
        A oab = ob;
        oa.m();
        ob.m();
        oab.m();

        System.out.println("AA"+oa.a);
        System.out.println("BB"+ob.a);
        System.out.println("AB"+oab.a);
    }
}

出力:

A0
B5
B5
AA0
BB5
AB0

理由がわかりませんoab.m(); 出力はA0ではなくB5です。誰かが私にこれを説明できますか?

4

7 に答える 7

9

それがポリモーフィズムの要点です。の具象型oabB(オブジェクトが で作成されたためnew B()) です。したがって、メソッドB.m()が呼び出されます。

http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29の動物の例を見て、なぜそれが役立つのかを理解してください。あなたが動物を飼っていて、その動物が猫である場合、あなたはそれが「ニャー!」と言うのを期待します。あなたがそれを話させるとき。

于 2012-07-04T10:46:34.743 に答える
1
B ob = new B();
A oab = ob;

に似ている

A oab=new B();

I don't understand why oab.m(); output is B5 instead of A0

オブジェクトを作成Bして A に参照しているためm()、継承されており、それがB's versionofm()が呼び出されている理由です。

于 2012-07-04T10:59:55.247 に答える
0

B の内部アドレスを A にコピーし、それを置き換えました。

B は A から継承するため、コンパイルの問題はありません。

最後に、A への参照が破棄され、B への参照のコピーになります。

于 2012-07-04T13:54:47.297 に答える
0
A oa = new A();
B ob = new B();
A oab = ob;

上記のコードから、ob はクラス B のインスタンスです。A が B を拡張するので、クラス A の変数に格納できます。しかし、格納された Object インスタンスは B のものであるため、A の m() 関数を認識しません。したがって、アウトプットは B5

于 2012-07-04T10:46:45.760 に答える
0

継承では、実際のメソッド呼び出しは、参照の型ではなく、実際のオブジェクトの型に依存します。

 B ob = new B();
 A oab = ob;

oabこれはタイプの参照変数ですが、タイプAのオブジェクトを指しています。つまりBob実行時にクラスからオーバーライドされたメソッドoab.m()を呼び出しますm()B

于 2012-07-04T10:47:28.370 に答える
0

Java には遅延バインディング (ポリモーフィズム) のようなものがあります。これは、メソッドのコードがコンパイル時 (早期バインディング) ではなく、実行時にリンクされることを意味します。JVMの呼び出し中は、参照oab.m();からオブジェクトの実際のタイプ(クラス)をチェックしaob(あなたの場合B)、そのクラスからメソッドのコードを呼び出すその情報に基づいています。oab.m();それが を返す理由B5です。

また、遅延バインディングはフィールドではなくメソッドに対してのみ機能することも知っておく必要があります。フィールドの値は参照型によって決定されるため、notoab.aを返します。05

于 2012-07-04T11:04:58.803 に答える
0

次のものがあったと想像してください。

public class C extends A {

public int a = 7 ;
public void m (){
    System.out.println("C"+a);
}

これが Main メソッドにあるとしたら...

C oc = new C();
A oac = oc;
oac.m();

...最後の呼び出しで、クラス C に固有のものを出力する必要があります。

ポイントは、B は Aであり、C は Aですが、それぞれに A に含まれる値のより具体的なバージョンがあり、それらのデータを要求すると、それらの特定のバージョンが返されるはずです。

今、あなたはこれを行うことができます:

// Get an instance of B or C, but you don't
// care which - could be either:
A someVersionOfA = getAnInstanceOfA(); 

// This works no matter if you've got an instance
// of B or C, but the result should vary accordingly:
someVersionOfA.m();

他の誰かが言ったように、Aを「動物」、Bを「猫」、Cを「犬」と考えてください。m()が「音を立てて」を意味する場合、m()を呼び出すと、「ニャー」または「ウーフ!」となるはずです。返されたインスタンスgetAnInstanceOfA()によって異なります。

于 2012-07-04T11:15:17.817 に答える