虚方法就一定带有virual(Overridable)吗?
上接"检测是否页面刷新还是第一次加载"的文章,谈到了自定义一个继承于Page的类(姑且称为MyPage吧)并且重写了OnInit方法,以后让其它的Page类全部继承自该类,突然想到一个问题——既然OnInit被重写了,那么以后继承于MyPage类的其它页面如果有特殊需要,还是要重写OnInit还可以吗?要知道OnInit被重写之后已经不带virtual(VB.NET中虚方法是Overridable),那就是一个普通方法,还可以被重写吗?
现在看来,这种担心是多余的——因为虽然这个方法不带virtual关键字,但是仍然是虚方法——看来可以这样总结:凡是overrides(VB.NET中Overrides)重写方法都是虚方法,只不过没有带虚方法的关键词罢了。
直接证明:
[C#]
namespace MyTest
{
class A
{
public virtual void Say()
{
Console.WriteLine("A");
}
}
class B:A
{
public override void Say()
{
Console.WriteLine("B:Say method is an virual method:"+MethodBase.GetCurrentMethod().IsVirtual);
}
}
class C:B
{
public override void Say()
{
Console.WriteLine("C:Say method is an virual method:"+MethodBase.GetCurrentMethod().IsVirtual);
}
}
class Program
{
static void Main(string[] args)
{
B b = new B();
b.Say();
C c = new C();
c.Say();
}
}
}
[VB.NET]
Namespace MyTest
Class A
Public Overridable Sub Say()
Console.WriteLine("A")
End Sub
End Class
Class B
Inherits A
Public Overrides Sub Say()
Console.WriteLine("B:Say method is an virual method:" + MethodBase.GetCurrentMethod().IsVirtual)
End Sub
End Class
Class C
Inherits B
Public Overrides Sub Say()
Console.WriteLine("C:Say method is an virual method:" + MethodBase.GetCurrentMethod().IsVirtual)
End Sub
End Class
Class Program
Private Shared Sub Main(args As String())
Dim b As New B()
b.Say()
Dim c As New C()
c.Say()
End Sub
End Class
End Namespace
MethodBase是一个内置的方法,位于System.Reflection命名空间下,用于检测当前方法(不仅是“方法”,还可以是属性、构造函数等)一些属性,其中IsVirtual就是检测是否是“虚方法”,结果的确是!看来不能“以貌取人”啊!
附带说一句:如果强制某个重写方法变得不再“虚”,就使用Sealed(VB.NET中是NotOverridable),就像为整个类做“绝育手术”一样(C#是sealed,VB.NET是NotInheritable),给你的方法做“绝育手术”吧,不过这貌似后话了……:-)
其实正如此篇报道的评论员评论的一样,我所要指出的是——任意一个继承自父类的对象,不仅仅是方法自身,连访问修饰符,以及是否是虚函数等特性也要一并继承。再次感谢评论员的点评!