3

そのため、クラスで示されたこの例を理解するのに少し苦労しています.Javaの静的型と動的型の間の微妙な点を説明することになっています。

public class Piece {

    public static void main (String[] args) {
        Piece p2 = new Knight();
        Knight p1 = new Knight();
        p1.capture(p2); // call 1; "Knight is bored" is supposed to be printed
        p2.capture(p1); // call 2; "knight is bored" is supposed to be printed
    }

    public void capture () {
        System.out.println("Capturing");
    }

    public void capture (Piece p) {
        System.out.println("I'm bored")
    }

public class Knight extends Piece {

    public void capture (Piece p) {
        System.out.println("Knight is bored");
    }

    public void capture (Knight k) {
        System.out.println("TOO SLOW BUDDY");
    }
}

2つの呼び出しが行われたときに何が起こるかについての私の理解は次のとおりです。

呼び出し 1: p1.capture(p2)

キャプチャ メソッドは p1 から呼び出されます。動的タイプのルックアップにより、p1 の動的タイプがKnightであることがわかります。したがって、Knight サブクラスに見えます。p2 が引数として渡されます。Knight サブクラス内で呼び出すキャプチャ メソッドを確認するために、p2のstatic型であるpieceをチェックします。そのため、「Knight is Bored」がプリントされています。これは正しい出力ですが、私の推論は正しいですか?

呼び出し 2: p2.capture(p1)

同じ理由で、capture メソッドは p2 から呼び出されます。動的型ルックアップを介して、p2 の動的型がKnightであることがわかります。したがって、Knight サブクラスに見えます。p1 が引数として渡されます。呼び出すキャプチャ メソッドを確認するために、p1 の静的型であるKnightを調べます。そのため、「TOO SLOW BUDDY」がプリントされています。明らかに、それは実際に印刷されたものではないため、私の推論は間違っています。方向性は?

ありがとう!

4

6 に答える 6

5

2 番目の呼び出しでは、Piece クラスのメソッドまたはそのサブクラスの同じメソッドのみを呼び出すことができます。そのため、capture(Knight k) の代わりに capture(Piece p) を呼び出します。後者は騎士クラスに固有のものです。

たとえば、"List a = new Arraylist();" がある場合、List で宣言されたメソッドのみを呼び出すことができ、ArrayList 内の追加の類似したメソッドは呼び出すことができません。

于 2012-06-28T05:28:22.023 に答える
2

sメソッドに@Overrideアノテーションを追加すると、それが明確になります。Knight

public void capture (Knight k) {
    System.out.println("TOO SLOW BUDDY");
}

このメソッドはオーバーライドされません。これは新しいKnightもので、クラスに追加されます。

したがって、次のタイプのオブジェクトでのみ使用できますKnight。例:Knight k = new Knight();

このメソッドが引数としてKnightで呼び出されるような例はありません。あなたは騎士と騎士、そして騎士と騎士をKnight呼び出しましたcapture

    p1.capture(p2); // call 1; "Knight is bored" is supposed to be printed
    p2.capture(p1); // call 2; "knight is bored" is supposed to be printed
    p1.capture(p1); // call 3:  TOO SLOW BUDDY <- look here :)
于 2012-06-28T05:30:00.337 に答える
2
 p2.capture(p1); // call 2; "knight is bored" is supposed to be printed

ここでは、Piece クラス オブジェクトのキャプチャ メソッドを呼び出しています。p1(Knight) クラス参照が渡されているため、Knight クラスのオーバーライドされたキャプチャ メソッドが呼び出されます。あれは

 public void capture (Piece p) {
        System.out.println("Knight is bored");
    }
于 2012-06-28T05:34:13.807 に答える
1

次のコードを実行すると -

public class Piece {

public static void main (String[] args) {
    Piece p2 = new Knight();
    Knight p1 = new Knight();
    p1.capture(p2); 
    p2.capture(p1); 
}

public void capture () {
    System.out.println("Capturing");
}

public void capture (Piece p) {
    System.out.println("I'm bored");
}

}

  class Knight extends Piece {


  //    public void capture (Piece p) {
  //        System.out.println("Knight is bored");
  //    }

public void capture (Knight k) {
    System.out.println("TOO SLOW BUDDY"+k);
}

}

結果は -

私は退屈です

私は退屈です

したがって、動的ルックアップは、サブクラスが関数をオーバーライドしたかどうかをチェックします。

于 2012-06-28T05:37:27.450 に答える
0

私が覚えているように、「拡張」とは「新しいものを古いものの上に置くが削除しない」ことを意味し、メソッドを「オーバーライド」している場合は、説明したようになります。あなたの場合、「p1.capture(p1)」を呼び出すと、「TOO SLOW BUDDY」になるはずです(ただし、試していません)。

于 2012-06-28T05:27:02.903 に答える
0

このサンプルは、静的型と動的型の違いを示しているとは思いません。スーパークラスとサブクラスについて考える必要さえありません。メソッド定義を伝えているだけです。---> 呼び出し元、メソッド名、パラメータの名前、パラメータの型がすべて同じ場合にのみ、正しいメソッドが呼び出されます。

于 2012-06-28T05:27:45.307 に答える