如何处理子类对象属性的{_clone

时间:2015-12-15 05:23:19

标签: php

当克隆作为另一个对象的子对象的对象时,是否“需要”指示作为子类__clone()方法中的对象的所有父属性,或者是否为子类__clone()方法只能包含自己不属于父对象的对象属性吗?

这是一个例子

对象Child_A扩展了对象Parent_A

对象Parent_A在其构造函数中使用对象A_1并使用__clone()方法。

class Parent_A{

   function __construct(A_1 $a_1){
      $this->A_1 = $a_1;
   }

   function __clone(){
      $this->A_1 = clone $this->A_1;
   }
}

对象Child_A需要A_2来构建。

class Child_A{

   function __construct(A_2 $a_2){
      parent::__construct(new A_1());

   }

   function __clone(){

      $this->A_2 = clone $this->A_2;
   }
}

如果我想制作包含deep_copy Child_A的{​​{1}}的深层副本,我应该在A_1中使用:

Child_A

或者以下内容足够,因为父对象的克隆方法已经包含 function __clone(){ $this->A_1 = clone $this->A_1; $this->A_2 = clone $this->A_2; }

A_1

谢谢。

2 个答案:

答案 0 :(得分:5)

首先,您的Child_A不会延伸Parent_A,所以这个结构

class Child_A {

    function __construct(A_2 $a_2){
        parent::__construct(new A_1());
    }
}

在第一次尝试实例化该类时导致致命错误。

其次,你没有使用$a_2,因此Child_A::__clone将会发出未定义变量A_2的通知。

最后,要回答这个问题 - 不,如果没有明确调用,则不会调用父级__clone。建议的解决方案是让子进程只处理它自己的属性的克隆,并让parent关注它的属性:

class Parent_A
{
    protected $a_1;

    function __construct(A_1 $a_1)
    {
        $this->a_1 = $a_1;
    }

    function __clone()
    {
        $this->a_1 = clone $this->a_1;
    }
}

class Child_A extends Parent_A
{
    protected $a_2;

    function __construct(A_2 $a_2)
    {
        $this->a_2 = $a_2;
        parent::__construct(new A_1);
    }

    function __clone()
    {
        $this->a_2 = clone $this->a_2;
        return parent::__clone();
    }
}

答案 1 :(得分:3)

似乎您需要DeepCopy。代码取自PHPExcel

public function __clone() {
    foreach($this as $key => $val) {
        if (is_object($val) || (is_array($val))) {
            $this->{$key} = unserialize(serialize($val));
        }
    }
}

还有一个名为DeepCopy的模块。

PHP文档还定义了Objects Cloning