0

ダミーテストを書くだけで確実に答えることができますが、人々がどう思っているのか知りたいです。ここにあります:

オーバーロードとオーバーライドの両方が同時に発生した場合、どちらのメソッドが呼び出されますか?私はタイプのオーバーロードのみを考慮しており、アリティのオーバーロードは考慮していません。タイプのオーバーロードは関連しています。

例を挙げましょう。

class AA {}
class BB : AA {}

class A {
    public virtual void methodA(AA anAA) { Console.Write("A:methodA(AA) called"); }
    public virtual void methodA(BB aBB) { Console.Write("A:methodA(BB) called"); }
}

class B : A {
    public override void methodA(AA anAA) { Console.Write("B:methodA(AA) called"); }
}

new B().methodA(new BB());     // Case 1
new B().methodA(new AA());     // Case 2
new B().methodA((AA)new BB()); // Case 3

ケース1、2、3で何が起こるかわかりますか?

私は個人的に、過負荷は悪であり、予測可能な答えにつながる可能性のある一貫した考え方はないと思います。そして、それは完全にcompiler+vmに実装された規則に基づいています。

編集:過負荷が悪である理由について疑問がある場合は、GiladBrachのブログ投稿を読むことができます

ありがとう

4

3 に答える 3

6

いいえ、完全に予測可能です。メソッド シグネチャが最初に解決されます。つまり、オーバーロードが最初に決定されます。次に、最もオーバーライドされたメソッドが呼び出されます。したがって、出力は次のようになります。

  • A:methodA(BB) が呼び出されました
  • B:methodA(AA) と呼ばれる
  • B:methodA(AA) と呼ばれる

AA のインスタンスを取るメソッドは、2 番目の 2 つのケースで呼び出されます。これは、渡される参照の型であり、呼び出されるのは B のバージョンであるためです。これでも同じ結果になることに注意してください。

A instance = new B();
instance.methodA((AA)new BB()); // Case 3
于 2012-06-01T14:02:05.717 に答える
4

オーバーライドされたメソッドは、コンパイラが呼び出すメソッドを決定するときに、メソッド セットから除外されます。メンバー検索アルゴリズムを参照してください。したがって、 type を呼び出すとmethodA、 typeからのB名前を持つメンバーのセットとその基本型が構築されます。methodAB

override B.methodA(AA)
virtual A.methodA(AA)
virtual A.methodA(BB)

ovveride次に、修飾子がセットから削除されたメンバー:

virtual A.methodA(AA)
virtual A.methodA(BB)

このメソッドのグループは、ルックアップの結果です。その後、呼び出すメンバーを定義するためにオーバーロードの解決が適用されます。

  1. A.methodA(BB)引数がパラメーターと一致するため、呼び出されます。
  2. A.methodA(AA)が選択されますが、これは仮想メソッドであるため、実際には呼び出しがB.method(AA)
  3. オプション 2 と同じ
于 2012-06-01T14:01:38.740 に答える
0

結果はこうなると思います

ケース 1 : Console.Write("A:methodA(BB) が呼び出されました");

ケース 2 : Console.Write("B:methodA(AA) が呼び出されました");

ケース 3 : Console.Write("B:methodA(AA) が呼び出されました");

ケース3では、渡されたタイプに見え、それはBです

于 2012-06-01T14:02:54.000 に答える