我被告知static
方法是隐式的final
,因此不能被覆盖。真的吗?
有人可以举一个更好的覆盖静态方法的例子吗?
如果静态方法只是类方法,那么拥有它们的真正用途是什么?
我被告知static
方法是隐式的final
,因此不能被覆盖。真的吗?
有人可以举一个更好的覆盖静态方法的例子吗?
如果静态方法只是类方法,那么拥有它们的真正用途是什么?
(1) 静态方法不能被覆盖,但是可以使用'new'关键字隐藏它们。大多数覆盖方法意味着您引用基类型并希望调用派生方法。由于静态是类型的一部分,并且不受没有意义的 vtable 查找的影响。
例如静态不能做:
public class Foo {
public virtual void Bar() { ... }
}
public class Bar : Foo {
public override void Bar() { ... }
}
// use:
Foo foo = new Bar(); // make an instance
foo.Bar(); // calls Bar::Bar
因为静态不适用于实例,所以您始终明确指定 Foo.Bar 或 Bar.Bar。所以覆盖在这里没有意义(尝试在代码中表达它......)。
(2) 静态方法有不同的用法。例如,它在 Singleton 模式中用于获取类型的单个实例。另一个例子是“static void Main”,它是程序中的主要访问点。
基本上,只要您不想或不能在使用之前创建对象实例,就可以使用它们。例如,当静态方法创建对象时。
[更新]
一个简单的隐藏示例:
public class StaticTest
{
public static void Foo() { Console.WriteLine("Foo 1"); }
public static void Bar() { Console.WriteLine("Bar 1"); }
}
public class StaticTest2 : StaticTest
{
public new static void Foo() { Console.WriteLine("Foo 2"); }
public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1
}
public class TestStatic
{
static void Main(string[] args)
{
StaticTest2.Foo();
StaticTest2.Some();
StaticTest.Foo();
Console.ReadLine();
}
}
请注意,如果您制作课程static
,则不能这样做。静态类必须派生自object
.
The main difference between this and inheritance is that the compiler can determine at compile-time which method to call when using static. If you have instances of objects, you need to do this at runtime (which is called a vtable lookup).
好吧,您不能覆盖静态方法。静态方法不能是虚拟的,因为它与类的实例无关。
派生类中的“重写”方法实际上是一种新方法,与基类中定义的方法无关(因此使用了 new 关键字)。
理解这一点很重要:当类型从其他类型继承时,它们履行一个共同的契约,而静态类型不受任何契约的约束(从纯 OOP 的角度来看)。语言中没有技术方法可以将两种静态类型与“继承”契约联系在一起。如果您要在两个不同的地方“覆盖” Log 方法。
如果您考虑覆盖静态方法,那真的没有意义;为了进行虚拟调度,您需要一个对象的实际实例来检查。
静态方法也不能实现接口;如果这个类正在实现一个 IRolesService 接口,那么我认为该方法根本不应该是静态的。拥有实例方法是更好的设计,因此您可以在准备好时将 MockRoleService 换成真实的服务