如果我调用继承的重载,将调用什么方法

本文关键字:调用 什么 方法 继承 如果 重载 | 更新日期: 2023-09-27 18:34:39

假设我有这个:

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.同时适用于FooAdvancedFoo SuperiorFoo,那么哪一个将被调用,为什么?

如果我调用继承的重载,将调用什么方法

编辑了我的答案,现在问题已被修改。

快速跟踪显示以下内容:

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(( 方法。

它会在 SuperiorFoo 中不断调用 Bar(( 方法,直到它因 StackOverflowException 而崩溃。如果你想调用 Bar(( 的基本方法(也就是 AdvancedFoo 中的方法(,你需要使用这个:

base.Bar(target);

编辑:

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

尽管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(,它将上升到适当的链...