2

ここにc#コードがあります

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

の出力

Console.WriteLine(((A)clB).Foo()); // output 5 <<<--
Console.WriteLine(((A)clB).Bar()); // output 1

この出力を取得するにはどうすればよいですか。ここでクラスのキャストプロセスを説明できる人はいますか?

アップデート:

そして、これはシャドウイングとオーバーライドの違いをどのように示していますか

4

4 に答える 4

6

私はそれを仮定します

var clB = new B();

FooBarメソッドの違いは、Barは継承とポリモーフィズムを使用して呼び出す実装を決定する一方で、Fooメソッドは元の実装を隠していることです。

つまり、A.Foo()B.Foo()はまったく関係がなく、たまたま同じ名前を持っているだけです。A型の変数が呼び出されることをコンパイラが認識すると、メソッドが仮想ではないため、メソッドが呼び出さFooれて実行さA.Foo()れるため、オーバーライドすることはできません。同様に、変数に含まれるインスタンスの実際の型に関係なく、実行する型のB変数を参照します。FooB.Foo()

一方、Barメソッドは仮想として定義されており、継承クラスはその実装をオーバーライドできます (また、オーバーライドすることが期待されます)。そのため、またはBarとして宣言された変数からの呼び出しであるかに関係なく、への呼び出しが行われるときはいつでも、実際に呼び出されるメソッドは、呼び出しオブジェクト自体の階層内で「最新の」実装として検出される必要があります。オブジェクトを参照するために使用された変数の型。AB

于 2013-02-06T14:23:00.570 に答える
0
var clB = new B();
//Uses B's Foo method
Console.WriteLine(clB.Foo());    // output 1
//Uses A's Foo method since new was use to overload method
Console.WriteLine(((A)clB).Foo()); // output 5
//Uses B's Bar Method
Console.WriteLine(clB.Bar());    // output 1
//Uses B's Bar Method since A's Bar method was virtual
Console.WriteLine(((A)clB).Bar()); // output 1
于 2013-02-06T14:27:27.460 に答える
0

classでは、既存のメソッド (から継承) と同じ名前とシグネチャを持つメソッドをB導入します。同じ名前の 2 つのメソッドがあります。それを避けることができれば、それはあなたがすることではありません。newFooAB

2 つのメソッドのどちらFooが呼び出されるかは、使用される変数または式 ( または の型) のコンパイル時の型によって異なります。AB

対照的に、方法Barvirtual. Barのメソッドは1 つだけBです。式のコンパイル時の型が何であれ、呼び出されるのは常に「正しい」オーバーライドです。

于 2013-02-06T14:26:36.617 に答える
0

書き込み

((A)clB).Foo()

は、「 (できれば) であるかのように扱い、結果を教えてくださいclB」と言っているようなものです。は非仮想メソッドを持っているため、 を実行します。のメソッドは " " メソッドであるため、このインスタンスでは使用されません。AFoo()AFooA.FooBFoonew

書き込み

((A)clB).Bar()

は似ています - " (できれば) でclBあるかのように扱い、 " の結果を教えてください。仮想メソッドが追加されました。これは、基本クラスでオーバーライドできることを意味します。オブジェクトは実際には for を持つであるため、代わりに が呼び出されます。ABar()A BarBoverrideFoo()B.Foo()

于 2013-02-06T14:27:21.340 に答える