2

Java の本を読んでいて、Dynamic Method Dispatch に出会いました。しかし、それは私にとって少し混乱しました(たぶん私が初心者だったからでしょう)。この本は、スーパークラスの参照変数はサブクラスのオブジェクトを参照できるという原則に基づいていると述べています。

    class X{
    void display()
    {
       System.out.println("This is class X");
    }
    }

    class Y extends X{
    void display()
    {
        System.out.println("This is class Y");
    }
    void play()
    {
        System.out.println("PLAY!");
    }
    }

    class k{
    public static void main(String args[]){
    X obj1 = new X();
    Y obj2 = new Y();
    X ref  = new X();

    ref = obj1;
    ref.display();
    //output is :This is class X

    ref = obj2;   //Using the principle stated above
    ref.display();
    //output is :This is class Y

    ref.play();  //Compiler error:Play not found 
    //well it must be because ref is of X type and for X no methods of its subclass "Y"
    //is visible
    }
    }

play() が表示されない場合、なぜ Y の display() が表示されるのですか??

4

4 に答える 4

0

実行前に、Java プログラムはコンパイラによって処理されます。Compiler は、とりわけ、既存のメソッドのみが呼び出されるようにします。上記の場合、コンパイラーは、宣言されているようにrefが型Xであり、型Xにメソッドplayがないことだけを知っています。すべての割り当てを追跡するわけではなく、型Yのobj2によってrefが割り当てられたことを考慮しません。このような追跡は、コンパイル時に利用できないランタイム データに依存する可能性があるため、一般的には不可能です。

一方、実行時のメソッド呼び出しは、宣言された型の拡張である可能性がある実際の型に依存します。コンパイラによって発行されたまったく同じコードが、変数refによって参照されるオブジェクトの実際の型に応じて、メソッドdisplayのさまざまな実装を呼び出すことができます。ただし、コンパイラは、refに割り当てられる可能性のあるオブジェクトのすべての可能なタイプに対してメソッドdisplayが存在することを確認します。

于 2013-07-14T08:30:05.020 に答える
0

静的型チェックにより、参照の静的 (宣言された) 型に属するメソッドのみを呼び出すことができます。そのため、タイプ X の参照を介して .play() を呼び出すことはできません。

ただし、動的メソッド ディスパッチにより、メソッドがサブクラスでオーバーライドされた場合、その特定のメソッドが (実行時に) 動的に呼び出されることが保証されます。

于 2013-07-14T06:20:55.223 に答える