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()),为什么?我猜它会被级联调用,但我不知道为什么以及是否保证了这种行为。

更新

那么,base.两者都适用于FooAdvancedFoofor SuperiorFoo,那么将调用哪一个,为什么?

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

它将继续调用 SuperiorFoo 中的 Bar() 方法,直到它因 StackOverflowException 而崩溃。如果你想调用 Bar() 的基本方法(即 AdvancedFoo 中的方法),你需要使用这个:

base.Bar(target);

编辑:

看起来原始帖子中的代码已更改。现在发生的事情是,SuperiorFoo 的 'Bar' 将调用 AdvancedFoo 的 'Bar',而 AdvancedFoo 的 'Bar' 将调用 Foo 的 'Bar',然后代码将被终止。

于 2012-05-17T11:35:35.053 回答
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 回答