【发布时间】:2014-02-08 21:46:46
【问题描述】:
我打算在父对象的构造函数中创建对象父对象的克隆。简而言之:
class ParentClass {
protected $property;
public function __construct() {
$this->property = clone $this;
}
}
class ChildClass extends ParentClass {
}
这一切都很好,但是这段代码的问题是受保护的属性被一个 ChildClass 的实例填充,以防 ChildClass 被实例化。但是,无论$this 指的是什么类,我都希望它成为 ParentClass 的一个实例。
我当然可以结合debug_backtrace 和new self()(为了避免构造函数调用的无休止递归)并将生成的 ParentClass 实例分配给属性,尽管这样的解决方案很冗长,因为调试回溯只返回字符串名称调用者类和方法。
最后,我可以结合new self() 和为对象的实例化提供一个参数来指示是否应该创建一个“新自我”,但我不喜欢这个解决方案,因为它的丑陋和冗余。
有没有办法在 PHP 中找到“自我克隆”?
【问题讨论】:
-
你实际上想用这个实现什么?为什么一个对象需要一个自己的克隆作为成员,如果它是一个不同的类,它在什么意义上是一个克隆?对此的传统解读是“ChildClass is-a ParentClass”和“ChildClass has-a ParentClass”,但由于某种原因not“ChildClass has-a ChildClass”......我怀疑有一种不那么令人费解的方式来做任何打算实现的目标。
-
@IMSoP 我的消息记录器对象可以被其他对象扩展。任何“公共”消息记录器(任何脚本都可以实例化)也需要它自己的私有消息记录器,以便记录它自己的——例如——错误消息。现在,当我实例化一个从基本消息记录器继承的邮件记录器时,我不希望私人消息记录器属于邮件记录器类型,而是保留基本消息记录器类型。
-
在这种情况下,也许“内部记录器”首先不应该是基类,而是完全不同的对象。你可以有一个抽象的
PublicLogger类,它的部分定义是实例化一个PrivateLogger对象(或者在构造函数中提供它,如“依赖注入”)。即使没有内部记录器,邮件记录器也没有从“基本”(日志到文件?)记录器继承的业务,而不是它们都具有共同的abstract基础或interface。 -
另外,忘记内部记录器的整个概念,只需在(抽象)基本记录器类上使用
protected方法,例如log_internal_logging_error,用于任何最后的错误处理或调试记录器需要记录。 -
@IMSoP 消息记录器记录消息并可能对它们执行某些操作(取决于已在对象上设置的标志)。最后,如果要求,它可以以某种方式导出消息。邮件记录器也是如此,尽管它的某些方法已稍作修改。我经常在需要记录自己的错误的类中注入基本消息记录器的实例。对我来说,如果我对消息记录器类本身做同样的事情是有意义的。