You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带默认实现的接口方法继承重定义问题及多态表现差异咨询

问题解答

一、为何同一实例调用Foo()表现出不同行为?

在第一段代码中:

  • MyUpperScript 继承自 MyScript,而 MyScript 靠接口的默认方法实现了 IInterface。
  • MyUpperScript 里定义的 public void Foo() 是全新的类成员,它既没有实现接口的Foo,也没有覆盖基类的同名成员,只是隐藏了基类继承来的接口默认实现。
  • 通过 MyUpperScript 类型变量调用Foo()时,会直接执行子类自己定义的方法,输出Upper Script。
  • 当把实例转为IInterface类型调用Foo()时,由于子类没有实现接口的Foo,会使用基类继承的接口默认实现,输出Interface。

而当MyUpperScript显式声明继承IInterface后,子类的public void Foo()会被视为接口Foo方法的实现,此时无论通过子类类型还是接口类型调用,都会执行子类的方法,因此两次输出都是Upper Script。

二、如何在继承类中重新定义接口带实现体的函数而不覆盖?

核心是区分“隐藏基类成员”和“实现接口方法”,可以通过以下方式实现:

1. 显式声明继承接口并提供公共实现

像你修改后的代码那样,让子类同时继承基类和接口,此时子类的public Foo()会自动成为接口方法的实现,既重新定义了接口方法的行为,又不会覆盖基类的成员(基类本身没有自定义Foo,仅依赖接口默认实现)。

2. 显式实现接口方法

如果不想让子类的Foo成为公共方法,或者需要区分子类自身方法和接口方法,可以显式实现接口:

public class MyUpperScript : MyScript, IInterface
{
    // 子类自身的公共Foo方法
    public void Foo()
    {
        Console.WriteLine("Upper Script - Public");
    }

    // 显式实现接口的Foo方法
    void IInterface.Foo()
    {
        Console.WriteLine("Upper Script - Interface Implementation");
    }
}

此时:

  • 通过MyUpperScript类型调用Foo()会输出Upper Script - Public
  • 通过IInterface类型调用Foo()会输出Upper Script - Interface Implementation

3. 复用接口默认实现(可选)

如果需要在子类的实现中复用接口的默认逻辑,可以通过IInterface.Foo(this)调用:

public class MyUpperScript : MyScript, IInterface
{
    public void Foo()
    {
        Console.WriteLine("Upper Script");
        // 调用接口的默认实现
        IInterface.Foo(this);
    }
}

内容的提问来源于stack exchange,提问作者Murat Serhat Alperen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:40:23