6

我一直在寻找一种方法来调用类似于“parent::_ construct”但用于类本身的类的构造函数(类似于“self:: _construct”,尽管这不起作用)。为什么要这样做?考虑以下(这不起作用,顺便说一句)......

class A {
  var $name;
  function __construct($name) {
    $this->name = $name;
  }
  function getClone($name) {
    $newObj = self::__construct($name);
    return $newObj;
  }
}

class B extends A {
}

在实际实现中,还有其他属性可以区分 B 类和 A 类,但两者都应该具有“getClone”方法。如果在 A 类的对象上调用它应该产生另一个 A 类的对象,如果在 B 类上调用它应该产生另一个 B 类的对象。

当然,我可以通过在 B 类中重写“getClone”并将类名硬编码到方法中来做到这一点(即,$newObj = new B($name)),但是只对方法进行编码会更好一次,告诉它实例化自己类的对象,无论该类是什么。

PHP会让我这样做吗?

4

3 回答 3

4

您可以使用

 $clsName = get_class($this);
 return new $clsName();

但 niko 的解决方案也有效,对单例模式有用http://php.net/manual/en/language.oop5.static.php

从 php 5.3 开始,您可以使用static关键字的新功能。

<?php

abstract class Singleton {

    protected static $_instance = NULL;

    /**
     * Prevent direct object creation
     */
    final private function  __construct() { }

    /**
     * Prevent object cloning
     */
    final private function  __clone() { }

    /**
     * Returns new or existing Singleton instance
     * @return Singleton
     */
    final public static function getInstance(){
        if( static::$_instance == null){
            static::$_instance = new static();
        }
        return static::$_instance;
    }
    
}
?>
于 2012-06-07T07:30:52.013 回答
2

您不仅可以使用变量,还可以使用与类相关的特殊关键字,例如“self”或“static”来创建新实例:$newObj = new static($name);- 这将创建当前类的新实例。

您可能应该考虑使用对克隆对象的内置支持:$copy = clone $instance;- 您可以通过指定魔术方法 __clone() 轻松扩展该运算符在类实例上的行为。

class A {
  var $name;
  function __construct($name) {
    $this->name = $name;
  }
  function getClone($name) {
    $newObj = new static($name);
    return $newObj;
  }
}

class B extends A {
}

$tmp = new A('foo');
$a = $tmp->getClone('bar');
// $a instanceof A => true, $a instanceof B => false

$tmp = new B('foo');
$b = $tmp->getClone('bar');
// $b instanceof A => true, $b instanceof B => true
于 2012-06-07T06:35:34.437 回答
0

你想要做的是使用内置的对象克隆功能http://php.net/manual/en/language.oop5.cloning.php

但是对于您关于调用构造函数的直接问题,您应该做的是创建一个 init() 函数,并将所有 __constructor 代码放入 init() 并让 __constructor 调用 init()

于 2012-06-07T06:29:11.580 回答