关于类:为什么要返回新的静态?

Why return new static? (PHP)

为什么有些人创建一个返回新静态的方法而不是使所有方法都是静态的?使用返回新静态值的方法的原因是什么?我不是在问静态和自我之间有什么区别,或者静态和自我意味着什么。例如,这里有一个简单的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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()返回新的static。然后,有些人调用其他方法,如:

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

它的目的是什么?我看到这里我们不使用新的表达式语法,如果这就是重点——那么为什么它们不让所有的方法都是静态的呢?有什么区别,为什么要使用返回新静态值的方法?


new static从当前类中实例化一个新对象,并使用后期的静态绑定(实例化子类如果该类是子类的,我希望您理解这一点)。

在返回同一个新实例的类上具有static方法是一个可选的构造函数。也就是说,通常您的构造函数是public function __construct,通常需要一组特定的参数:

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

有了一个可选的构造函数,您就可以提供不同的默认值或方便的快捷方式来实例化这个类,而无需提供这些特定的参数和/或提供可选的构造函数将转换为规范的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
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之外什么都不做,那么它可能只是作为(new Foo)->的便利语法,我觉得这有问题。


get_called_class()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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(B::get_self());  // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A