Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle __clone for child class object properties

Tags:

php

When cloning an object that is a child of another object, is it "required" to indicate all the parent properties that are objects in the child class __clone() method or does the child class __clone() method can only include its own object properties that does not belong to the parent object?

Here is an example

The object Child_A extends the object Parent_A.

The object Parent_A uses the object A_1 in its constructor and has a __clone() method.

class Parent_A{

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

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

The object Child_A requires A_2 to construct.

class Child_A{

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

   }

   function __clone(){

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

If I want to make a deep copy of Child_A that would include a deep_copy A_1, should I use in Child_A:

   function __clone(){

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

Or is the following enough as the parent object's clone method already includes A_1:

   function __clone(){

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

Thank you.

like image 561
Vincent Avatar asked Feb 08 '23 07:02

Vincent


1 Answers

First of all, your Child_A does not extend Parent_A, so this construction

class Child_A {

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

results with fatal error on the first attempt to instantiate the class.

Secondly, you make no use of $a_2 there, so Child_A::__clone will result with notice of undefined variable A_2.

Finally, to answer the question - no, if not explicitly called, parent's __clone is not invoked. The recommended solution is to let the child handle clone of its own properties only, and let parent take care about its properties:

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();
    }
}
like image 173
Alex Blex Avatar answered Feb 10 '23 21:02

Alex Blex