PHP静态工厂方法:动态实例化调用类的实例

时间:2015-02-15 17:40:35

标签: php static runtime subclass factory

这个PHP问题与this question有关,但有点不同。我有一个名为create()的静态工厂方法,它实例化一个类实例。我希望该方法动态实例化调用它的(子)类的实例。因此,它必须在运行时确定它实例化的类。但是我想这样做而不必重新定义子类中的静态工厂方法(这在我的例子中完全有效,因为子类没有新的数据成员来初始化)。这有可能吗?

class Foo {

  private $name;

  public static function create($name) {

    //HERE INSTED OF:
    return new Foo($name);
    //I WANT SOMETHING LIKE:
    //return new get_class($this)($name);//doesn't work
    //return self($this);//doesn't work either

  }

  private function __construct($name) {

    $this->name = $name;

  }

  public function getName() {

    return $this->name;

  }

}

// the following class has no private data, just extra methods:

class SubFoo extends Foo {

  public function getHelloName() {

    echo "Hello, ", $this->getName(), ".\n";

  }

}


$foo = Foo::create("Joe");
echo $foo->getName(), "\n"; // MUST OUTPUT: Joe

$subFoo = SubFoo::create("Joe");
echo $subFoo->getHelloName(), "\n"; // MUST OUTPUT: Hello, Joe.

3 个答案:

答案 0 :(得分:5)

return new static();

已经保留了关键字static

答案 1 :(得分:5)

您必须使用Late Static Binding创建对象 - 方法get_called_class()非常有用。第二个选项是使用static关键字。

示例:

class Foo 
{
    private $name;

    public static function create($name) 
    {
        $object = get_called_class();
        return new $object($name);
    }

    private function __construct($name) 
    {
        $this->name = $name;
    }

    public function getName() 
    {
        return $this->name;
    }
}

class SubFoo extends Foo 
{
    public function getHelloName() 
    {
        return "Hello, ". $this->getName();
    }
}

$foo = Foo::create("Joe");
echo $foo->getName(), "\n";

$subFoo = SubFoo::create("Joe");
echo $subFoo->getHelloName(), "\n";

输出:

Joe
Hello, Joe

答案 2 :(得分:-3)

是的,可以使用php的后期静态绑定功能。

而不是

$foo = Foo::create("Joe");
echo $foo->getName(), "\n"; // MUST OUTPUT: Joe

$subFoo = SubFoo::create("Joe");
echo $foo->getHelloName(), "\n"; // MUST OUTPUT: Hello, Joe.

试试这个

echo parent::getName();
echo self::getHelloName();