OOP中静态函数有什么用途?

3

静态函数在面向对象编程中有什么用途?

它如何与其他函数区分?

4个回答

6
作为一个非常简单、有点牵强的例子:
class Foo {

    protected $bar = null;
    protected $baz = null;

    public function __construct($bar, $baz) {
        $this->bar = $bar;
        $this->baz = $baz;
    }

    public static function instantiateFromArray(array $data) {
        return new self($data['bar'], $data['baz']);
    }

}

$foo = new Foo('bar', 'baz');
// or
$foo = Foo::instantiateFromArray(array('bar' => 42, 'baz' => 'nine'));

在这种情况下,静态函数充当替代构造函数的作用,允许您从数据数组中构造对象,而不是使用单独的参数。
通常,静态函数提供围绕对象的功能,而无需实例化它。有很多用途。至少,完全静态的类可以用于捆绑函数和相关数据,这本身就使代码更清晰。这就是它们与普通函数的区别所在:普通函数无法保存“外部”数据(除非使用全局变量,但您不想这样做),而静态类方法可以将数据保存在静态类属性中。

这里应该将构造函数设为私有吗? - Sahal
在某些情况下,我们编写静态函数来创建新的实例,因为我们不允许直接为该类创建任何实例。这时我们将构造函数写为私有。我认为公共构造函数+静态函数不是创建OOP设计的正确方式(如果静态函数用于实例创建)。 - Sahal
正如我所写的那样,在这种情况下,静态方法是一种替代对象构造器。你可以通过 new FooFoo :: instantiateFromArray 创建实例,两者都接受不同类型的参数,但结果相同。Foo :: __construct标准构造函数Foo :: instantiateFromArray 是一种替代构造函数。没有必要将构造函数设为私有,只是为了强制调用者使用静态方法来实例化同一个对象。 - deceze

3

您不需要实例化对象即可使用静态方法/属性。

由于这个原因,它们无法在对象中存储状态。

它们经常被用作命名空间相关方法的一种方式,例如:

echo str::truncate($str, 100);

1

静态函数被用于在类实例不存在时调用类代码(在更纯粹的oop语言中)。静态函数可以改变静态变量。


0

将类属性或方法声明为静态的,使它们无需实例化类即可访问。声明为静态的属性不能通过已实例化的类对象访问(虽然静态方法可以)。

为了与 PHP 4 兼容,如果没有使用可见性声明,则该属性或方法将被视为公共声明。

因为静态方法可以在创建对象实例之前调用,所以在声明为静态的方法内部不可用伪变量 $this。

静态属性不能通过箭头运算符 -> 使用对象访问。

调用非静态方法静态生成 E_STRICT 级别警告。

与任何其他 PHP 静态变量一样,只能使用文字或常量初始化静态属性;不允许使用表达式。因此,虽然可以将静态属性初始化为整数或数组(例如),但不能将其初始化为另一个变量、函数返回值或对象。

class Foo
{
    public static $my_static = 'foo';

    public function staticValue() {
        return self::$my_static;
    }
}

class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
}


print Foo::$my_static . "\n";

$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n";      // Undefined "Property" my_static 

print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n"; // As of PHP 5.3.0

print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";

2
至少说一下你是从http://www.php.net/manual/en/language.oop5.static.php复制粘贴的。 - deceze

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