如何从PHP中的构造函数返回子类

时间:2011-07-08 09:02:18

标签: php oop

<?php

class Super {
    public $my;
    public function __construct ( $someArg ) {
        if ( class_exists('Sub') ) {    // or some other condition
            return new Sub( $someArg );
        }
        $this->my = $someArg;
    }
}

class Sub extends Super {}

?>

这不起作用,因为new Super()将是一个“空”Super对象(所有成员都是NULL)。 (PHP不允许对$this进行分配,因此$this = new Sub()也不起作用。)

我知道正确的模式将是这里的工厂。但这需要对代码进行大量更改,所以我想知道是否可以这样做。由于Sub是一个Super,我不明白为什么不应该从OOP的角度来限制它。

3 个答案:

答案 0 :(得分:5)

你在这里弄错了。构造函数没有返回值,你不能从构造函数返回一个实例 - 一旦调用了构造函数,类就被解决了,你就不能再改变它了。

您要做的是为此实施factory pattern

<?php

class Super {
    public $my;
    public function __construct ( $someArg ) {
        $this->my = $someArg;
    }

    public static function factory ($somearg) {
        if ( class_exists('Sub') && $somearg["foo"] == "bar") {    // or some other condition
            return new Sub( $someArg );
        }
        else {
            return new Super($someArg);
        }
    }
}

class Sub extends Super {}

$mynewsuborsuper = Super::factory($myargs);
?>

答案 1 :(得分:3)

您无法分配给$this,也无法从构造函数返回任何内容。

答案 2 :(得分:0)

使用PHP反射。当您使用工厂时,无需切换或继承。

<?php
class DocumentFactory
{
    public function create($className, $constructorArguments = array())
    {
        $reflection = new ReflectionClass($className);
        return $reflection->newInstanceArgs($constructorArguments);
    }
}

abstract class Document
{
    $protected $doc;
    public function __construct($string){$this->doc = $string;}
}

class XMLDocument extends Document
{
    public function __construct($string, $extraArg)
    {
        parent::__construct($string);
        //Do something else with $extraArg
    }
}

class HTMLDocument extends Document
{

}

$DFactory = new DocumentFactory();

$XMLDocument = $DFactory->create('MY\FULL\NAMESPACE\XMLDocument', array(//extra arguments));

//Or add .php at the end if you're not using namespaces