让我说我有这个:
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.
对Foo
的{{1}}和AdvancedFoo
都适用,那么将调用哪一个以及为什么?
答案 0 :(得分:6)
现在编辑我的答案,问题已被修改。
快速跟踪显示以下内容:
Entering SuperiorFoo.Bar()
Entering AdvancedFoo.Bar()
Entering Foo.Bar()
Leaving Foo.Bar()
Leaving AdvancedFoo.Bar()
Leaving SuperiorFoo.Bar()
让我们谈谈发生的事情:
SuperiorFoo.Bar()调用其基本方法。由于SF.Bar()继承 来自AdvancedFoo,它的基本方法是AdvancedFoo.Bar()。
AdvancedFoo.Bar()然后调用它的base,即Foo.Bar() AdvancedFoo继承自Foo()。
进程流不会从SF.Bar()跳转到Foo.Bar(),因为你可能想要中间类的行为。
如果我们从AdvancedFoo中删除该方法,则遍历略有不同。 SuperFoo.Bar()仍然会调用它的基本方法,但由于AdvancedFoo不再隐藏Foo.Bar()方法,逻辑将跳转到Foo.Bar()方法。
答案 1 :(得分:0)
它会继续在SuperiorFoo中调用Bar()方法,直到它与StackOverflowException崩溃。如果你想调用Bar()的基本方法(所以AdvancedFoo中的方法),你需要使用它:
base.Bar(target);
编辑:
看起来原帖子中的代码已更改。现在发生的事情是,SuperiorFoo的'Bar'将调用AdvancedFoo的'Bar',它将调用Foo的'Bar',之后代码将被终止。
答案 2 :(得分: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),它将上升到相应的链......