当一个类实现接口方法时,可以用C#进行标记和检查
本文关键字:检查 一个 方法 接口 实现 | 更新日期: 2023-09-27 18:26:04
当基类包含virtual
方法时,要在子类中添加更派生的版本,我们必须使用override
。
AFAICT,这有两个目的:
- 我们不会意外地覆盖基方法
- 如果我们在希望重写时键入了错误的方法名称,我们会得到一个错误(类似于Java,对吧?)
然而,令我沮丧的是,(在VS2010/.NET4中)在实现接口方法时,似乎不可能使用override
。
显然,第一个项目符号不是问题,但override
关键字可以作为一个很好的简单文档,并检查接口方法实际上是标记为override
的方法。
那么,当查看一个类实现时,除了// comment
之外,还有什么其他的方法可以表明这个方法实现了某个接口的方法吗?
然而,令我沮丧的是,(在VS2010/.NET4中)在实现接口方法时似乎不可能使用重写。
这是因为接口方法不是重写的,而是实现的。这是一个看似微不足道的语义差异,但当我们谈论语言的使用时,语义是非常重要的。
但是override关键字可以作为一个很好的简单文档,并检查接口方法是否实际上是标记为override 的方法
这不是有点误导吗?override
意味着有一个基类定义被重写了。MSDN文档将其定义为:
重写修饰符是扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现所必需的。
接口不是继承的,而是实现的。同样,只是语义,但有一个非常重要的区别。一个类可以实现多个接口,相同的方法可以应用于多个接口定义,等等。
重写继承的行为意味着:
- 有继承的行为(在
virtual
的情况下有默认实现,在abstract
的情况下没有),请记住C#是一种单一的继承语言 - 实现被重写(当父类内部调用该成员时,它在继承模型中带有特定的区别)
这些条件不适用于接口。
那么,在查看类实现时,除了//注释之外,还有其他方法可以表明该方法实现了某个接口的方法吗?
事实上,是的。您可以显式地实现接口。类似这样的东西:
interface IDimensions
{
float Length();
float Width();
}
class Box : IDimensions
{
public float IDimensions.Length()
{
// implementation
}
public float IDimensions.Width()
{
// implementation
}
}
我相信你关心的一切都可以用这句话来概括:
但是override关键字本来是一个很好的简单记录并检查接口方法是否实际为标记为覆盖。
想想什么是接口,什么是实现者。类可以实现也可以不实现接口,并且仍然可以实现与接口具有相同签名的方法。接口所做的工作是确保某些类具有完成契约所需的成员。
例如,类Calculator
可以实现ICalculator
,而Calculator
实现Addition(int, int)
。但是Calculator
不能实现ICalculator
,无论如何它都可以执行Addition(int, int)
。
你如何区分这两种情况?何时使用override
。
另一点:实现一个类,实现一个接口,并通过在继承冒号后从类签名中删除它来停止实现它是很好的。
另一方面,假设您要查找的文档是编译器错误,告诉您Calculator
实现了接口ICalculator
,但它没有声明和实现ICalculator
定义的一个或多个成员。如果代码是编译的,则不应该关心成员是某个接口还是其他接口。您知道有些成员是某个接口的实现,因为您的Calculator
签名看起来像这样:public class Calculator : ICalculator
。
此外,还有一种情况是,实现成员实现它来实现的不仅仅是接口。什么凌驾于您的实现之上?这不是比回避override
关键字更令人困惑吗?
假设您有以下类型:
interface ISampleInterface
{
void Method();
}
class A : ISampleInterface
{
public void Method()
{
}
}
class B : A, ISampleInterface
{
void ISampleInterface.Method()
{
}
}
class C : A, ISampleInterface
{
public new void Method()
{
}
}
并以这种方式使用它们:
ISampleInterface a = new A();
ISampleInterface b = new B();
ISampleInterface c = new C();
a.Method(); // calls A.Method
b.Method(); // calls explicit ISampleInterface.Method
((B)b).Method(); // calls A.Method
c.Method(); // calls C.Method
((A)c).Method(); // calls A.Method
看起来很难定义Method
的哪些实现可以标记为override
。