什么更好?静态方法还是实例方法?

10

我发现有两种方法称为静态方法和实例方法,并且它们之间存在差异。但是我仍然无法理解一种方法比另一种更具优势。

有时我觉得静态方法不是100%面向对象的。

这两种方法之间是否存在性能差异。

有人可以帮忙吗?

7个回答

7
在完美的面向对象世界中,可能不需要静态方法(我认为Eiffel也没有)。但归根结底,重要的不是你的代码的纯粹面向对象性(C#有足够多的概念并不严格遵循面向对象原则,例如扩展方法),而是你所完成的工作。
您可以使用静态方法作为通用帮助方法(它们不需要通用帮助类或自己的状态)或像Color.FromARGB()这样的东西,对于值类型行为略微像构造函数。
一般来说,任何不涉及对象状态(因此比对象特定更适用于类的方法)的方法都可以被设置为静态方法。性能差异不应该真正出现。无论如何,都不是非常可测量的。Jan Gray的优秀文章编写更快的托管代码:了解成本有一些关于此的硬数据,尽管需要小心处理。

2
即使在一个“纯面向对象的世界”中,我也不明白将Math.Cos变为实例方法如何更符合“面向对象”的原则。对于这样的实用方法,静态方法和实例方法之间在概念上没有区别,无论是使用N个参数的静态方法,还是使用N-1个参数的实例方法,其中“this”被理解为第一个参数("Math.Cos(double)" VS "double.Cos()")。 - Trillian

6
静态方法的主要用处在于无需实例化对象即可调用该方法。例如,静态方法可能用于查找现有实例并返回它(单例实例就是一个例子)。
正如其他人所说,如果方法不访问状态,您可以将任何方法设为静态方法,并获得微小的性能提升。
如果您想要在特定实例上调用该方法并获得多态的好处(例如,派生类可以重写方法的行为),则应将其设置为实例方法。
如果您的类实现接口,则属于这些接口的方法也必须声明为实例方法。

6
实例方法是与实例紧密相关联的。因此,您可以看到静态方法的一个优点是不与实例相关。其他对象可以使用静态方法(如果可见)来解决它们的问题。有时这很好并且必要。然后你需要考虑将静态方法保留在同一类中还是开始构建用于更广泛使用的实用程序类。
我认为静态方法的用处并没有“不太面向对象”。静态方法是规避 OO 缺陷的一种方式 (特别是在单继承语言中)。你可以称之为更函数式的方法 (我知道它并不是真正的)。
探讨所有这些只是一堆应该问你的代码的问题,并且应该决定是否最好使用实例方法、同一类的静态方法或另一个类的静态方法。
我甚至不会想到性能问题。这将削弱您的设计,而差异并不是很大。性能在您有性能问题时很重要。

2

1
请注意,只有在您尝试在非常慢的平台上执行某些操作或每秒执行数十万次操作时,才应考虑速度参数。我猜您正在使用一款>2 Ghz双核处理器。成员函数调用和静态函数调用之间的速度差异不应成为设计标准。 - Harald Scheirich
1
是的,即使在速度较慢的平台上,这也不应该成为设计考虑因素(正如我在答案中所说)。我只是注意到性能差异,因为它被明确提出了。 - Mehrdad Afshari

2

如果你的方法使用了非静态数据成员,不要将其设为静态(你“无法”这样做)。

如果你的方法没有使用任何非静态数据成员,你可以将其设为静态,但这主要取决于你的设计而不是它是否使用非静态成员(无论如何,性能上没有太大差别,正如Mehrdad所说)。

如果你的类中没有非静态数据成员,有时最好将所有方法都设为静态(例如,在为了良好的组织而将辅助函数分组到一个类中的情况下)。


1

我只是根据C#的继承猜测,但我认为它与其他面向对象的语言相同。

静态方法不需要对象来操作。一个很好的例子就是:

Double pi = Math.PI.

实例方法需要一个对象。一个例子是这样的:

Integer x = 9;
Integer y = x.sqrt();

并不是所有属于一个类的信息都需要实例化对象才能访问。那些可以用于创建对象的常量(例如Math.PIWindow.OVERLAPPED等)就是这种情况的典型示例。

1
没有谁比另一个更好。这取决于您的需求。当您想要对整个类应用更改时,调用类方法。而当您不是将更改应用于类,而是将更改应用于该类的唯一实例(对象)时,需要调用实例方法。
因此,我认为没有一个比另一个更好的理由。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接