一个类是否应该有静态和非静态成员

时间:2010-01-29 23:58:19

标签: language-agnostic oop

我正在试图找出一个类何时同时具有静态和非静态函数。 AKA:

$obj = new ClassA;
$obj->doOOPStuff();

$something = ClassA::doStaticStuff();

注意:此示例在PHP中完成,但问题与语言无关。

似乎如果你有一个要实例化的类,任何可以静态调用的函数,很可能属于另一个类。

有没有可行的案例,我会有一个使用静态和非静态成员的类?

10 个答案:

答案 0 :(得分:7)

一个例子:当创造必须以特定方式发生时。

class Foo {
public:
  static Foo* Create(...params...);

private:
  Foo();
};

答案 1 :(得分:5)

考虑.NET中的String类。它包含一个非静态Split方法,该方法将某些实例分解为string[]和静态Join方法,该方法接受string[]并再次将其转换为字符串。< / p>

当您不需要保持任何状态时,静态方法适用。所以Math.Sin()只取决于它的参数,并且在给定相同参数的情况下,输出将始终相同。非静态方法可以多次调用不同的行为,因为它可以保持内部状态。

答案 2 :(得分:3)

如果静态方法提供的功能与该类及其对象相关,为什么不呢。这很常见。

答案 3 :(得分:2)

  • 静态方法通常是工厂方法

    public class MyClass {    
        public static MyClass createMyClass(int a, double b) {..}
        public static MyClass createSubclassOfMyClass(int c, boolean cond) {..}
        public int calculateThis();
        public double calculateThat();
    }
    
  • 另一个用途是访问某个属性,该属性在逻辑上绑定到该类,但不能单独访问实例。例如 - 缓存:

(注意 - 当然在这个例子中应考虑同步)

public class MyClass {
    public static final Cache cache = new Cache();
    public static void putInCacheIfNeeded(Object obj) {..}
    public static void replaceInCache(Object obj) {..}

    public void doSomethingCacheDependend(Object obj) {
        if (something) {
             MyClass.putInCacheIfNeeded(obj);
        } else {
             MyClass.replaceInCache(obj);
        }
    }
}

(示例的Java语言)

答案 4 :(得分:1)

想象一下,你的构造函数有两个重载,都是字符串:

public class XmlDocument
{
    public static XmlDocument CreateFromFile(string filePath);
    public static XmlDocument CreateFromXml(string xml);
}

答案 5 :(得分:1)

静态函数可以为构造函数提供有意义的名称。

$dialog = DialogFoo::createOpenDialog();
$dialog = DialogFoo::createDocumentOpenDialog();
$dialog = DialogFoo::createImageOpenDialog();

它也可用于强制执行Singleton模式。

$dialog = DialogFoo::getInstance()

答案 6 :(得分:0)

静态类成员在所有必须位于对象中或位于全局范围内时最有用;它们在支持模块级范围的Python等语言中不太有用。

答案 7 :(得分:0)

当我不希望访问构造函数时,我使用静态方法来实例化新对象。我确保在创建和对象之前在类上执行任何必要的前提条件。在这个例子中,我有一个计数器来返回创建了多少个对象,如果我有10个对象,我会阻止它们被实例化。

class foo {
private:
static int count;
foo() {}

public:
static foo bar() {
count++;
if (count<=10){
return new foo;
} else {
return null;
}

答案 8 :(得分:0)

让我们假设一个类有实例方法,这里有一些使用静态方法的好用例:

对于静态实用程序方法

此类方法适用于任何实例,例如Java中的String.format(String, Object...)

当您不想为作业创建特定实例时使用它们。

对于静态工厂方法

工厂方法是简单地实例化Java API中的getInstance()valueOf()方法之类的对象的方法。 getInstance()是单例中的常规实例化方法,而valueOf()通常是类型转换方法,如String.valueOf(int)

使用它们通过对象缓存提高性能,在基于接口的框架(如Java中的Collections Framework)中,您可能希望返回子类型,以实现单例(咳嗽)。

答案 9 :(得分:0)

通常,静态函数会生成与类本身高度相关的功能。它可能是一些辅助函数,工厂方法等。在这种情况下,所有功能都包含在一个地方,它对应DRY原则,增加cohesion并减少coupling