MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Copierea obiectelor claselor

Atunci când se atribuie un obiect de clasă unei alte variabile, se creează o nouă referință la același obiect. De exemplu:

class Person{
   public $name;
   function __construct($name){
       $this->name = $name;
   }
}
$tom = new Person("Tom");
$bob = $tom;
$bob->name = "Bob";
echo $tom->name; // Bob

În acest caz, după atribuirea $bob = $tom;, ambele variabile vor indica același obiect. Prin urmare, dacă schimbăm proprietatea $name a unei variabile, această schimbare va afecta și cealaltă variabilă, deoarece ele se referă la același obiect.

Totuși, acest comportament poate fi nedorit dacă dorim ca după copiere variabilele să reprezinte obiecte independente. Pentru aceasta, PHP oferă operatorul clone:

class Person{
   public $name;
   function __construct($name){
       $this->name = $name;
   }
}
$tom = new Person("Tom");
$bob = clone $tom;      // copiem obiectul din $tom în variabila $bob
$bob->name = "Bob";
echo $tom->name; // Tom

Prin aplicarea operatorului clone, toate proprietățile care reprezintă tipuri primitive și array-uri sunt copiate în noul obiect. Totuși, ce se întâmplă dacă o proprietate a clasei reprezintă o altă clasă:

class Company{
   public $name;
   function __construct($name){ $this->name = $name; }
}
class Person{
   public $name, $company;
   function __construct($name, $company)
   {
       $this->name = $name;
       $this->company = $company;
   }
}
$microsoft = new Company("Microsoft");
$tom = new Person("Tom", $microsoft);

$bob = clone $tom;      // copiem obiectul din $tom în variabila $bob
$bob->name = "Bob";
$bob->company->name = "Google";   // schimbăm numele companiei lui Bob
echo $tom->company->name; // Google - și la Tom s-a schimbat numele companiei

Aici ne confruntăm practic cu aceeași situație ca în primul exemplu. Clasa Person conține o proprietate care reprezintă clasa Company. La clonarea obiectului:

$bob = clone $tom;

Ambele variabile $tom și $bob vor conține o referință la același obiect Company. Prin urmare, dacă schimbăm proprietățile acestui obiect printr-o variabilă:

$bob->company->name = "Google";

Schimbarea va afecta și cealaltă variabilă:

echo $tom->company->name; // Google

Pentru a rezolva această problemă, trebuie să definim metoda __clone în clasă. Aceasta este apelată la clonare și poate fi utilizată pentru a clona obiectele încorporate:

class Company{
   public $name;
   function __construct($name){ $this->name = $name; }
}
class Person{
   public $name, $company;
   function __construct($name, $company)
   {
       $this->name = $name;
       $this->company = $company;
   }
   function __clone()
   {
       $this->company = clone $this->company;
   }
}
$microsoft = new Company("Microsoft");
$tom = new Person("Tom", $microsoft);

$bob = clone $tom;      // copiem obiectul din $tom în variabila $bob
$bob->name = "Bob";
$bob->company->name = "Google";   // schimbăm numele companiei lui Bob
echo $tom->company->name; // Microsoft - la Tom numele companiei nu s-a schimbat

În acest caz, metoda __clone din clasa Person clonează și obiectul Company, asigurându-se astfel că variabilele $tom și $bob se referă la obiecte independente.

← Lecția anterioară Lecția următoare →