__clone class php_PHP对象克隆clone和魔术方法__clone()用法代码

PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析

本文实例讲述了PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法。分享给大家供大家参考,具体如下:

1.对象克隆 clone

PHP4面向对象功能一个很大的缺点,是将对象视为另一种数据类型,这使得很多常见的OOP方法无法使用,如设计模式。这些方法依赖于将对象作为引用传递给其他类方法,而不是作为值传递,而按值传递却是PHP的默认做法。幸好,PHP5解决了这个问题,现在所有对象在默认情况下都被视为引用。但是,由于所有对象都被视为引用而不是值,所以现在复制对象更为困难。如果尝试复制一个引用的对象,这只会指向原对象的地址位置。为了解决复制问题,PHP提供了一种克隆clone(关键字,不是方法)对象的显式方法。

可以在对象前面加clone关键字来克隆对象,如下:

destinationObject = clone targetObject;

克隆对象:

class Person{

var $name;

var $sex;

var $age;

function __construct($name, $sex, $age){

$this->name = $name;

$this->sex = $sex;

$this->age = $age;

}

function say(){

echo "我的名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" .$this->age . "
";

}

}

$person1 = new Person("张三三", "男", 23);

$person2 = clone $person1; //使用clone关键字克隆/复制对象,创建一个对象的副本

$person3 = $person1; //这不是复制对象,而是为对象多复制出一个访问该对象的引用

$person1->say(); //调用原对象中的说话方式,打印原对象中的全部属性值

$person2->say(); //调用副本对象中的说话方式,打印克隆对象中的全部属性值

$person3->say(); //调用原对象中的说话方式,打印原对象中的全部属性值

?>

2.魔术方法__clone()

在上面的程序中一共创建了两个对象,其中有一个对象是通过clone关键字克隆出来的副本。两个对象完全能独立,但他们中的成员及属性的值完全一样。如果需要对克隆后的副本对象在克隆时重新为成员属性赋初值,则可以在类中声明一个魔术方法“__clone()”。该方法是在对象克隆时自动调用的,所以就可以通过此方法对克隆后的副本重新初始化。__clone()方法不需要任何参数。将上例中的代码改写一下,在类中添加魔术方法__clone(),为副本对象中的成员属性重新初始化。

class Person{

var $name;

var $sex;

var $age;

function __construct($name, $sex, $age){

$this->name = $name;

$this->sex = $sex;

$this->age = $age;

}

function say(){

echo "我的名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" .$this->age . "
";

}

function __clone(){

$this->name = "李四四"; //为副本对象中的name属性重新赋值

$this->age = 10; //为副本对象中的age属性重新赋值

}

}

$person1 = new Person("张三三", "男", 23);

$person2 = clone $person1; //创建一个对象的副本,并自动调用类中的__clone()方法

$person1->say(); //调用原对象中的说话方式,打印原对象中的全部属性值

$person2->say(); //调用副本对象中的说话方式,打印克隆对象中的全部属性值

?>

运行结果:

我的名字:张三三,性别:男,年龄:23

我的名字:李四四,性别:男,年龄:10

3.单例类的加强:禁止克隆

对于一个类的对象,如果使用“clone运算符”,就会复制出一个和当前对象完全一样的新对象出来,并且,此时还会自动调用该类的魔术方法:__clone()(只要该类中有该方法)。

则要实现单例类,就应该对这个单例类的对象“禁止克隆”。在PHP中,为防止对单例类对象的克隆来打破单例类的上述实现形式,通常还为其提供一个空的私有 (private修饰的)__clone()方法。

首先来看“未做禁止克隆”的效果:

class SingetonBasic {

private static $instance; //静态变量要私有化,防止类外修改

private function __construct() { //构造函数私有化,类外不能直接新建对象

}

//private function __clone() {} //在__clone()前用private修饰,用来禁止克隆

public static function getInstance() { //公共的静态方法,public——外部的接口,static——不使用对象而是通过类名访问

if (!(self::$instance instanceof self)) { //私有静态变量$instance为空

self::$instance = new self(); //新建为自身的对象,并赋值给私有变量$instance

}

return self::$instance; //返回私有变量$instance

}

}

$a = SingetonBasic::getInstance();

$b = SingetonBasic::getInstance();

var_dump($a === $b); //结果为:boolean true a和b指向的是同一个对象

$c = clone $a;

var_dump($a === $c); //结果为:boolean false a和c指向的不是同一个对象

?>

运行结果为

boolean true

boolean false

我们“作禁止克隆”处理,即把上面代码中的

private function __clone() {} //在__clone()前用private修饰,用来禁止克隆

这行代码去掉注释。

运行结果为

boolean true

Fatal error: Call to private SingetonBasic::__clone()

也就是,在克隆的时候,自动调用了__clone(),但是该方法被private修饰,不能再类的外部直接调用,结果报错。

希望本文所述对大家PHP程序设计有所帮助。

PHP对象克隆clone用法示例

本文实例讲述了PHP对象克隆clone用法。分享给大家供大家参考,具体如下:

浅克隆:只是克隆对象中的非对象非资源数据,即对象中属性存储的是对象类型,则会出现克隆不完全

class B{

public $val = 10;

}

class A{

public $val = 20;

public $b;

public function __construct(){

$this->b = new B();

}

}

$obj_a = new A();

$obj_b = clone $obj_a;

$obj_a->val = 30;

$obj_a->b->val = 40;

var_dump($obj_a);

echo '
';

var_dump($obj_b);

运行结果如下:

object(A)[1]

public 'val' => int 30

public 'b' =>

object(B)[2]

public 'val' => int 40

object(A)[3]

public 'val' => int 20

public 'b' =>

object(B)[2]

public 'val' => int 40

深克隆:一个对象的所有属性数据都彻底的复制,需要使用魔术方法__clone(),并在里面实现深度克隆

class B{

public $val = 10;

}

class A{

public $val = 20;

public $b;

public function __construct(){

$this->b = new B();

}

public function __clone(){

$this->b = clone $this->b;

}

}

$obj_a = new A();

$obj_b = clone $obj_a;

$obj_a->val = 30;

$obj_a->b->val = 40;

var_dump($obj_a);

echo '
';

var_dump($obj_b);

运行结果如下:

object(A)[1]

public 'val' => int 30

public 'b' =>

object(B)[2]

public 'val' => int 40

object(A)[3]

public 'val' => int 20

public 'b' =>

object(B)[4]

public 'val' => int 10

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的clone()方法是Object类中定义的方法,它用于创建并返回当前对象的一个副本。这个副本就是一个新的对象,它与原始对象具有相同的属性和方法。通常情况下,我们需要在一个类中实现clone()方法来支持对象克隆克隆对象是在Java中处理对象的一种常见方式。通过克隆,我们可以在不修改原始对象的情况下创建该对象的一个副本。这在某些情况下是非常有用的,例如在多线程环境下,我们需要多个线程同时访问同一个对象,但是又不希望它们之间相互干扰。 在Java中,要使用clone()方法来实现对象克隆,我们需要满足两个条件: 1. 实现Cloneable接口:这个接口是一个标记接口,它没有任何方法,只是用来标记一个类可以被克隆。 2. 重写clone()方法:这个方法是Object类中的一个protected方法,需要在我们的类中进行重写。在重写这个方法时,我们需要调用super.clone()方法来创建一个新的对象,并将原始对象中的属性复制到这个新对象中。 下面是一个示例代码,演示了如何在Java中实现对象克隆: ``` public class MyClass implements Cloneable { private int value; public MyClass(int value) { this.value = value; } public int getValue() { return value; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } ``` 在这个示例代码中,我们实现了一个MyClass类,并重写了clone()方法。在这个方法中,我们调用了super.clone()方法来创建一个新的对象,并返回这个新对象。由于我们的类实现了Cloneable接口,因此它可以被克隆。 使用这个类进行克隆代码如下: ``` MyClass obj1 = new MyClass(10); MyClass obj2 = (MyClass) obj1.clone(); System.out.println(obj1.getValue()); // 输出10 System.out.println(obj2.getValue()); // 输出10 ``` 在这个代码中,我们创建了一个MyClass对象obj1,并将其克隆为obj2。由于这两个对象具有相同的属性和方法,因此它们的输出结果也是相同的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值