带默认实现的接口方法继承重定义问题及多态表现差异咨询
问题解答
一、为何同一实例调用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
相关产品推荐
相关产品推荐

