所以我理解静态方法或字段是什么,我只是想知道何时使用它们。也就是说,在编写代码时,设计适合使用静态方法和字段。
一种常见的模式是使用静态方法作为静态工厂,但这可以通过重载构造函数来轻松完成。正确?例如:
var bmp = System.Drawing.Bitmap.LoadFromFile("Image01.jpg");
对于静态字段,是否最好使用singelton-objects?
答案 0 :(得分:28)
静态方法通常对不需要来自类实例(来自this
)的任何数据的操作有用,并且可以仅使用其参数执行其预期目的。
一个简单的例子是方法Point::distance(Point a, Point b);
,它计算两点之间的距离,不需要实例。
静态字段对于那些不会经常更改并且被类的所有实例使用的常量非常有用。
答案 1 :(得分:16)
当您使用静态工厂时,它更好地了解了意图 - 它还允许您拥有采用相同参数类型但具有不同含义的不同工厂。例如,假设Bitmap有LoadFromResource(字符串) - 就不可能有两个构造函数都接受了字符串。
编辑:来自评论中的stevemegson
静态工厂也可以返回null,并且可以更容易地返回从缓存中获取的实例。我的许多类都有一个静态FromId(int)来从主键获取实例,如果有的话,返回一个现有的缓存实例。
答案 2 :(得分:9)
我会说,只要你拥有独立于实例状态的函数,就使用静态方法。不依赖于任何实例字段。
方法所依赖的非本地状态越少,理解就越容易,因此static
对代码的读者来说是一个有用的信号。
答案 3 :(得分:7)
我通过记住实例方法在单个对象上/内部工作而保持清晰,而静态方法为类做了一些事情。
对于LoadFromFile(),您需要静态方法,因为如果加载失败,您需要空引用 - 实例尚不存在。如果您将其实现为构造函数,则必须在失败时抛出异常。
静态的其他好的用法:比较(obj a,obj b),删除(obj a)数据对象(一个对象因为它的引用仍然存在而无法自行删除),或者是诚实的过程代码的静态类无法在对象中建模。
答案 4 :(得分:2)
只要有一个不依赖于该类的特定对象的函数,就应该使用静态方法。
添加static关键字没有任何害处:它不会破坏任何引用它的代码。因此,例如,无论您是否具有“static”关键字,以下代码均有效:
class Foo
{
public Foo(){}
public static void bar(){} // valid with or without 'static'
public void nonStatic(){ bar(); }
}
...
Foo a = new Foo();
a.bar();
所以你应该为你能用的任何方法添加'静态'。
答案 5 :(得分:1)
以下是您可能希望使用静态方法的一些示例:
1)当函数没有使用任何成员变量时。您不必在此处使用静态方法,但如果您这样做,通常会有所帮助。
2)使用工厂方法创建对象时。如果您事先不知道要创建的类型,则特别需要它们:例如
class AbstractClass {
static createObject(int i) {
if (i==1) {
return new ConcreteClass1();
} else if (i==2) {
return new ConcreteClass2();
}
}
}
3)当您控制或以其他方式跟踪班级的实例化数量时。 Singleton是最常用的例子。
4)声明常量时。
5)对类的多个对象进行操作的操作,例如排序或比较,并且不与任何特定实例绑定。
6)在第一次实例化对象之前必须进行特殊处理。
答案 6 :(得分:0)
当类的客户端没有要使用的类的实例时,您可以使用静态方法。例如,Singleton设计模式用于确保系统中只存在一个类的实例。它要求Singleton的构造函数是私有的,以便客户端不能创建任何实例。
因此,如果您无法创建实例,那么如何访问该类的实例方法?通过调用返回类的Singleton实例的静态方法。
这当然只是一种情况,但还有很多其他情况。
答案 7 :(得分:0)
当方法不属于特定对象时,请使用静态方法。
例如,如果你看一下.NET框架中的Math类,你会看到
所有方法都是静态的。为什么?因为没有理由必须创造
一个使用这些方法的对象。你为什么要创建一个对象?
Math
类,当你想要的只是某些东西的绝对价值?不在这里
没有理由这样做,因此,该方法是静态的。
所以当你设计课程时,问问自己:
此方法是属于对象还是类本身?
如果方法修改了对象的状态,则该方法属于对象。如果 该方法不会修改特定对象,它很可能是静态的。
另一个例子,假设您想知道一个类的对象数量
这是创造的(不要问我为什么......)。对于此任务,您可以创建一个
静态方法GetNumberOfObjects()
(你显然需要一个静态字段,
以及构造函数中的一些代码)。你为什么我会把它静止
问。好吧,回答上面的问题,你会看到。该方法没有
属于任何特定的对象。此外,它不会修改任何对象。
我希望这是有道理的。