/** * 电视机类 */ class Television { /** * 电视机编号 */ protected $_identity = 0; /** * 屏幕高度 */ protected $_screenLength = 300; /** * 屏幕宽度 */ protected $_screenHight = 200; /** * 电视机外观颜色 */ protected $_color = 'black'; /** * 遥控器对象 */ protected $_control = null; /** * 构造函数中加载遥控器对象 */ public function __construct() { $this->setControl(new Telecontrol()); } /** * 设置遥控器对象 */ public function setControl(Telecontrol $control) { $this->_control = $control; return $this; } /** * 返回遥控器对象 */ public function getControl() { return $this->_control; } /** * 返回电视外观颜色 */ public function getColor() { return $this->_color; } /** * 设置电视机外观颜色 */ public function setColor($color) { $this->_color = (string)$color; return $this; } /** * 返回电视机编号 */ public function getIdentity() { return $this->_identity; } /** * 设置电视机编号 */ public function setIdentity($id) { $this->_identity = (int)$id; return $this; } public function __clone() { $this->setIdentity(0); } } /** * 遥控器类 */ class Telecontrol { }
方法1:直接复制对象
//直接复制对象,改变任意一对象属性,其他对象属性也会改变 $tv1 = new Television(); $tv2 = $tv1; echo 'color of tv1 is: ' . $tv1->getColor();//tv1的颜色是black echo '<br>'; echo 'color of tv2 is: ' . $tv2->getColor();//tv2的颜色是black echo '<br>'; //把tv2涂成白色 $tv2->setColor('white'); echo 'color of tv2 is: ' . $tv2->getColor();//tv2的颜色是white echo '<br>'; echo 'color of tv1 is: ' . $tv1->getColor();//tv1的颜色是white
方法2:通过clone对象方法将属性初始化
//通过clone 方法 $tv1 = new Television(); $tv2 = clone $tv1; echo 'color of tv1 is: ' . $tv1->getColor();//tv1的颜色是black echo '<br>'; echo 'color of tv2 is: ' . $tv2->getColor();//tv2的颜色是black echo '<br>'; //把tv2换成涂成白色 $tv2->setColor('white'); echo 'color of tv2 is: ' . $tv2->getColor();//tv2的颜色是white echo '<br>'; echo 'color of tv1 is: ' . $tv1->getColor();//tv1的颜色是black
clone方法的优缺点
优点:方法1中,php因为是引用方式,实际复制对象都指向同一对象地址,故改变其中任意对象属性值所有对象的对应属性都会相应改变,为此PHP5提供了一个专门用于复制对象的操作,也就是 clone 。这就是对象复制的由来。
缺点:使用clone操作复制对象时,当被复制的对象有对其它对象的引用的时候,引用的对象将不会被复制。
解决方法1:__clone
public function __clone() { //重新设置一个引用对象(引用多少个对象设置多少对象) $this->setIdentity(0); $this->setControl(new Telecontrol()); }
解决方法2:利用串行化做深复制
PHP有串行化(serialize)和反串行化(unserialize)函数,我们只需要用serialize()将一个对象写入一个流,然后从流中读回对象,那么对象就被复制了。在Java语言里面,这个过程叫做“冷藏”和“解冻”。