46

为什么一些开发人员创建一种返回新静态的方法?有一个返回 new static的方法的原因是什么?我不是在问静态和自我之间有什么区别,或者静态和自我是什么意思。例如,这是一个简单的类:

<?php

class Expression
{
    public static function make()
    {
        return new static;
    }


    public function find($value)
    {
        return '/' . $value .'/';
    }

    public function then($value)  
    {
        return $this->find($value);
    }

    public function hi($value)  
    {
        return "hi";
    }

}

如您所见,有一个静态方法make()返回new static。然后,一些开发人员调用其他方法,如下所示:

$regex = Expression::make()->find('www');

这样做的目的是什么?我看到这里我们不使用new Expression语法,如果这就是重点 - 那么为什么不将所有方法都设为静态呢?有什么区别,有一个返回新静态的方法(而其他方法不是静态的)的原因是什么?

4

2 回答 2

61

new static从当前类实例化一个新对象,并使用后期静态绑定(如果类是子类,则实例化子类,我希望你明白这一点)。

在类上拥有一个static返回相同新实例的方法是另一种构造函数。意思是,通常您的构造函数是public function __construct,并且通常它需要一些参数:

class Foo {
    public function __construct(BarInterface $bar, array $baz = []) { ... }
}

拥有替代构造函数允许您提供不同的默认值或方便快捷方式来实例化此类,而无需提供这些特定参数和/或能够提供替代构造函数将转换为规范参数的不同参数:

class Foo {

    public function __construct(BarInterface $bar, array $baz = []) { ... }

    public static function fromBarString($bar) {
        return new static(new Bar($bar));
    }

    public static function getDefault() {
        return new static(new Bar('baz'), [42]);
    }

}

现在,即使您的规范构造函数需要一堆复杂的参数,您也可以创建类的默认实例,这对于大多数用途来说可能都很好,只需使用Foo::getDefault().

PHP 中的典型示例是DateTimeDateTime::createFromFormat

在您的具体示例中,替代构造函数实际上并没有做任何事情,所以它是多余的,但我希望这是因为它是一个不完整的示例。如果确实有一个替代构造函数除了 之外什么都不做new static,它可能只是为了方便语法 over (new Foo)->,我觉得这是有问题的。

于 2016-05-26T12:44:26.610 回答
23

完整答案在这里

TLDR
get_called_class()

class A {
    public static function get_self() {
        return new self();
    }

    public static function get_static() {
        return new static();
    }
}

class B extends A {}

echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A
echo get_class(B::get_self());  // A
echo get_class(B::get_static()); // B
于 2017-04-17T16:34:41.900 回答