回答
(1)静态方法不能被覆盖,但可以使用'new'关键字隐藏。大多数重写方法意味着你引用一个基类型并想调用派生方法。由于静态是类型的一部分,并且不受vtable查找的影响。
E.g.静不能做:
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
派生。
这个和继承之间的主要区别是编译器可以在编译时确定使用静态时要调用哪个方法。如果您有对象的实例,则需要在运行时执行此操作(称为vtable查找)。
谢谢你给我重写的例子。是的,我尝试了代码。所以为了做到这一点,1)**我们可以像任何其他非静态类一样为子类静态类**吗? 2)我们可以使用静态方法而不用重写父类的静态方法,但使用New关键字隐藏它们。 – aspiring 2013-02-12 09:40:45
我加了一些解释和例子。 (1)不,你不能分类静态类,但你可以隐藏静态成员。 (2)是的,你应该尝试第二个例子,它告诉它如何表现。 – atlaste 2013-02-12 10:11:45
什么时候这个Foo <->酒吧废话结束???停止使用FoorBar作为示例,在每种情况下,Bar和Foo都是类或子类或函数或方法。所以点什么?只需使用动物进行子类化和重写操作即可。 10x – 2014-10-27 16:59:31
您不重写静态方法。你隐藏它。有关更多信息,请参阅this answer。
的部分原因是使用静态方法:
- 他们是一个比little bit faster实例方法。另请参阅此msdn article,其中提供了性能数字以支持此功能(内联静态呼叫平均值为0.2 ns,静态呼叫平均值为6.1ns,内联实例呼叫平均值为1.1 ns,实例呼叫平均值为6.8 ns)
- 不详细写出 - t需要实例化一个类以获得它们(并且实例化也可以影响性能)
我对实例方法没有任何问题。我了解到'static'类不能被实例化。但是你提到“静态方法是它只在你的应用中实例化了一次”。所以我现在很困惑。你是指'使用System.Math;'通过说静态方法被实例化?我一直在同一个类中多次使用Math类成员Math.Abs(),而没有将它们实例化一次。 1)那么你能否请你澄清你的意思***“实例化一次”***? 2)静态类可以是子类吗?子类静态类是否有意义? – aspiring 2013-02-12 08:53:58
看到我的编辑。我不应该用静态方法使用术语“实例化”。更正确的是说它只创建一次。 – 2013-02-12 09:03:06
所有*方法*仅“创建”一次。即使非静态方法也只有一个代码副本(在编译时创建的IL代码,在运行时一次*转换为机器代码)。不要混淆代码和数据!一个非静态方法只能通过一个对象的实例被调用,但这是因为隐藏的“this”指针被传递给它。代码本身是“静态的”,因为它是固定的和单例的。 – 2013-02-12 09:12:13
那么你不能覆盖静态方法。静态方法不能是虚拟的,因为它与类的实例无关。
派生类中的“overriden”方法实际上是一种新方法,与基类中定义的方法无关(因此与new关键字无关)。 (从纯OOP的观点来看),这是一个很重要的事情要理解:当类型从其他类型继承,它们履行一个公共契约,而静态类型不受任何契约约束。在语言中没有技术方法将两种静态类型与“继承”合同绑定在一起。如果你想在两个不同的地方“覆盖”Log方法。
如果您考虑过度使用静态方法,它并没有什么意义;为了有虚拟调度,你需要一个对象的实际实例来检查。
静态方法也不能实现接口;如果这个类正在实现IRolesService接口,那么我会争辩说该方法不应该是静态的。具有实例方法的设计更好,因此您可以在准备就绪时用真实服务替换MockRoleService
- 1. 我们可以有一个虚拟的静态方法吗? (C++)
- 2. 重写一个静态方法
- 3. Java重写静态方法
- 4. 一个静态方法总是可以转换为一个实例方法吗?
- 5. 可以隐藏静态方法吗?
- 6. 我可以在Objective-C中内联静态类方法吗?
- 7. 在java中的静态方法,我可以以非静态方式访问静态方法吗?
- 8. C#静态方法重构
- 9. 重写Set的contains()方法可以吗?
- 10. 我可以用特征中的方法重写一个scala类方法吗?
- 11. 可以重写一个隐藏的方法吗?
- 12. pyqt4:我可以重写一个没有子类的方法吗?
- 13. 调用synchronized静态方法,那么可以访问其他静态方法吗?
- 14. 作为一种静态方法编写一个非静态方法
- 15. 这个方法可以做成静态的吗?
- 16. 是否有可能重写派生类中的静态方法?
- 17. C#调用一个静态方法
- 18. 我可以用Cython创建一个静态C数组吗?
- 19. 我可以在java的静态方法中使用非静态变量吗?
- 20. 您可以在静态上下文中引用非静态方法吗?
- 21. 从另一个静态方法中调用静态方法
- 22. 我可以多态访问静态方法吗?
- 23. 可以在.cpp中声明/定义静态方法吗?
- 24. from/where我可以在类中调用静态类方法吗?
- 25. 静态方法可以在Java中调用它自己吗?
- 26. 你可以在同一个c#或C++类中有静态和实例方法吗?
- 27. C++中的静态方法
- 28. C#中的静态方法?
- 29. 在C#中,属性可以应用于静态类,方法或属性吗?
- 30. findViewById一个静态方法
不,它们不能被覆盖。他们与班级相关,而不是与对象相关联。 – 2013-02-12 08:23:13
供实际使用:您可以调用不带类实例的静态方法。 – Najzero 2013-02-12 08:23:54
谢谢。我明白[静态方法是什么](http://stackoverflow.com/a/4124118/2061309),SLak提供了最好的例子。所以对于我的问题重写一个静态方法(如果bydefault是最终的,而不是用户使其最终) - 这是否意味着没有这个类的子类,它拥有一个静态可以定义一个静态方法具有相同的签名? – aspiring 2013-02-12 08:28:54