2

私がこれを持っているとしましょう:

class A { }
class B : A { }
class C : B { }

class Foo
{
    public void Bar(A target) { /* Some code. */ }
}

class AdvancedFoo : Foo
{
    public void Bar(B target)
    {
        base.Bar(target);
        // Some code.
    }
}

sealed class SuperiorFoo : AdvancedFoo
{
    public void Bar(C target)
    {
        base.Bar(target);
        // Some code.
    }
}

実行するとどのオーバーロードが呼び出され、new SuperiorFoo().Bar(new C())その理由は? カスケード的に呼び出されると思いますが、その動作が保証されている理由とその動作が保証されているかどうかはわかりません。

更新しました

では、とforのbase.両方で機能します。どちらが呼び出されるのでしょうか。なぜですか?FooAdvancedFooSuperiorFoo

4

3 に答える 3

6

質問が改訂されたので、私の回答を編集しました。

クイック トレースは、次のことを示しています。

Entering SuperiorFoo.Bar()
Entering AdvancedFoo.Bar()
Entering Foo.Bar()
Leaving Foo.Bar()
Leaving AdvancedFoo.Bar()
Leaving SuperiorFoo.Bar()

何が起こるかを話しましょう:

  1. SuperiorFoo.Bar() は、その基本メソッドを呼び出します。SF.Bar() は AdvancedFoo を継承しているため、基本メソッドは AdvancedFoo.Bar() です。

  2. 次に、AdvancedFoo.Bar() は、そのベースである Foo.Bar() を呼び出します。これは、AdvancedFoo が Foo() を継承しているためです。

中間クラスからの動作が必要になる可能性があるため、プロセス フローは SF.Bar() から Foo.Bar() にジャンプしません。

AdvancedFoo からメソッドを削除すると、トラバーサルが少し異なります。SuperFoo.Bar() は引き続きその基本メソッドを呼び出しますが、AdvancedFoo は Foo.Bar() メソッドを非表示にしないため、ロジックは Foo.Bar() メソッドにジャンプします。

于 2012-05-17T11:33:48.823 に答える
0

KingCronus は基本的に無限ループを指摘しましたが。署名は、最初にオブジェクトの正確なタイプに基づいて適切なメソッドに一致させようとし、次にそれから下降する必要があります...

class Foo
{
    public void Bar(A target) { /* Some code. */ }
}

class AdvancedFoo : Foo
{
    public void Bar(B target)
    {
        base.Bar( (A)target );
        // continue with any other "B" based stuff
    }
}

sealed class SuperiorFoo : AdvancedFoo
{
    public void Bar(C target)
    {
        base.Bar( (B)target ); 
        // continue with any other "C" based stuff
    }
}

「その他」のタイプ (つまり、B または A) に型キャストすることにより、適切なチェーンに移動します...

于 2012-05-17T11:43:36.620 に答える
0

StackOverflowException でクラッシュするまで、SuperiorFoo 内で Bar() メソッドを呼び出し続けます。Bar() の基本メソッド (つまり AdvancedFoo 内のメソッド) を呼び出したい場合は、これを使用する必要があります。

base.Bar(target);

編集:

元の投稿のコードが変更されたようです。ここで起こることは、SuperiorFoo の「Bar」が AdvancedFoo の「Bar」を呼び出し、それが Foo の「Bar」を呼び出し、その後コードが終了するということです。

于 2012-05-17T11:35:35.053 に答える