为什么 virtual、abstract 和 override 关键字对静态函数无效?其背后的逻辑是什么?
5 回答
通过虚拟分派的多态性是通过使用目标实例的实际运行时类型来完成的,即实际obj
在obj.Bar(...args...)
. 现在:如果你没有实例,讨论多态obj.
是没有意义的。
静态方法是用静态调用调用的,而不是虚拟调用;关于调用什么方法的决定完全是在编译时做出的。没有任何决定要做。它归结为SomeType
in SomeType.SomeMethod(...args...)
。当然,您仍然可以在虚拟方法中的方法之间调用 - 您仍然可以访问SomeBaseType.SomeOtherStaticMethod(...)
.
事实上,存在将多态性概念扩展到静态方法的语言。不过,C# 不是其中一种语言。你不能通过某种类引用调用静态函数,所以你实际上没有机会在那里做任何“多态”的事情。
关键字virtual
,abstract
和override
与继承的方法一起使用。静态方法不会被继承。
静态方法实际上只是特定类的一部分,作为方法的占位符。静态函数不与声明它们的类共享生命周期或范围,它们实际上并不是对象模型的一部分。
这些关键字(抽象、虚拟、覆盖)与继承模型相关,在静态上下文中没有意义。
您不应该通过实例访问静态方法。 当你这样做时,C# 并不关心变量中的对象类型。它取决于变量的类型。也就是说,从头开始;在我的 Visual Studio 版本中,使用默认设置,您甚至不允许通过实例使用静态方法。无论哪种方式,这意味着MyType obj = null; obj.StaticMethod();
有效,因为从不咨询该对象。virtual static
不会做任何有价值的事情;virtual
并override
通过咨询对象来决定使用什么方法,并且使用static
,您只有类型(实际上是硬编码的,因此对多态性毫无用处)。 abstract
基本上是“override
在你的课堂上需要一个”,它'
我想 C# 的人让你假装静态的东西可以被覆盖并不难……但它不能。为了调用它,您必须指定类型(明确地喜欢MyType.StaticMethod()
,或隐含地如上所述)。他们选择明确表示你不能拥有虚拟静态方法并让它像你期望的那样工作,让你根本无法做到这一点。