鉴于此界面
public interface IMyInterface
{
string Method1();
}
为什么这是有效的
public sealed class InheretedFromInterfaceSealed: IMyInterface
{
public string Method1()
{
return null;
}
}
但这不是
public class InheretedFromInterfaceWithSomeSealed: IMyInterface
{
public sealed string Method1()
{
return null;
}
}
然而,它是抽象类的有效方案
public abstract class AbstractClass
{
public abstract string Method1();
}
public class InheretedFromAbstractWithSomeSealed: AbstractClass
{
public sealed override string Method1()
{
return null;
}
}
答案 0 :(得分:6)
因为默认情况下每个方法都是密封的,除非它是虚拟的,或者除非你没有对已经虚拟的东西说sealed
并且你正在覆盖。
答案 1 :(得分:1)
默认情况下,类中的每个方法都是密封的(NotOverridable
在VB.NET中),除非您在VB.NET中明确声明它为virtual
(Overridable
)。
正如你所说,这是不类的情况。您必须明确指出要禁止使用sealed
(或VB.NET中的NotInheritable
)从类继承。
答案 2 :(得分:0)
提醒一下,C#中的界面方法不能是sealed
。
请考虑以下代码:
interface IFoo
{
void Bar();
}
class Base : IFoo
{
public void Bar() { Console.WriteLine("Base.Bar"); }
}
class Derived : Base, IFoo
{
public new void Bar() { Console.WriteLine("Derived.Bar"); }
}
然后,如果我们有var d = new Derived()
,我们就会:
d.Bar()
撰写Derived.Bar
((Base)d).Bar()
撰写Base.Bar
((IFoo)d).Bar()
撰写Derived.Bar
((IFoo)(Base)d).Bar()
撰写Derived.Bar
派生类重写接口方法Bar
。 sealed
方法 接口方法,但方法为Base
。
也就是说,隐式实现
class ImplicitImpl : IFoo
{
public void Bar() { Blah; }
}
应被视为以下语义上等效的显式实现:
class ImplicitImplEquiv : IFoo
{
public void Bar() { Blah; }
void IFoo.Bar() { this.Bar(); }
}
如果派生类ImplicitImplEquiv
只是将public void Bar
隐藏到另一个public void Bar
,则调用((IFoo)ref).Bar()
仍会调用ImplicitImplEquiv.Bar
。但是,如果派生类还重新发送IFoo
并提供新的实现,则接口vtable将与ImplicitImplEquiv
的接口不同。
有关此主题的更多讨论,您可能需要阅读我的博客文章https://geelaw.blog/entries/csharp-interface-sealed/(该文章目前仅提供中文,但包含可帮助您了解问题的优秀代码段。)