概念:
原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过标准构造函数来创建。在原型模式中,新对象的创建是通过克隆现有对象而实现的,因此它是基于原型对象的复制而创建新对象的。
在Java中,原型模式通常通过实现 Cloneable 接口和重写 clone() 方法来实现。Cloneable 接口是一个标记接口,它指示了该类的实例可以被克隆。然后,通过重写 clone() 方法来实现对象的克隆。
换一个方式理解
:
原型模式就像是制作复印件一样。假设你有一份文件,想要多份一模一样的,但是你又不想重新从头写一遍。这时候,你可以使用原型模式:先制作一份原始文件,然后通过复制这份原始文件,就可以得到多份完全相同的副本。
代码1:
java">/*** 怎么实现克隆。拷贝?* 1、实现一个接口:* 2、重写一个方法*/
public class Video implements Cloneable{//克隆视频private String name;private Date createTime;/*** 重写克隆方法* @return* @throws CloneNotSupportedException*/@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public Video(String name, Date createTime) {this.name = name;this.createTime = createTime;}public Video() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Video{" +"name='" + name + '\'' +", createTime=" + createTime +'}';}
}
我们这有一个视频类。实现了Cloneable
接口并重写clone()
方法。这个clone()方法调用父类的克隆方法。而这个父类中的clone()是在本地克隆
测试类
java">import java.util.Date;/*** 客户端。实现克隆*/
public class BiliBiliClient {public static void main(String[] args) throws CloneNotSupportedException {Date date = new Date();//需要一个原型对象实现克隆//原型对象叫做v1Video v1 = new Video("Java从入门到精通", date);System.out.println("v1=====>"+v1);System.out.println("v1.hashCode=====>"+v1.hashCode());//v1可以克隆v2Video v2 = (Video) v1.clone();System.out.println("v2=====>"+v2);System.out.println("v2.hashCode=====>"+v2.hashCode());//修改v2的值v2.setName("张三");System.out.println(v2);}
}
创建一个BliBlili客户端类实现克隆,首先,我们先把原型对象创建出来,v1
的hashCode输出。我们在想创建一个v2对象的时候,传统的方式是不是还需要new Video对象,但是现在我们可以直接使用v1.clone()
方法进行创建,返回的是一个Object类。强制转换成Video对象。在进行把克隆的内容V2进行输出。此时两个对象内容一样,但是hashCode不一样
测试结果:
问题:
V2对象是V1对象拷贝过来的。但是他们还是指向同一个地址。
验证:
修改客户端的代码:
java">import java.util.Date;/*** 客户端。实现克隆*/
public class BiliBiliClient {public static void main(String[] args) throws CloneNotSupportedException {Date date = new Date();//需要一个原型对象实现克隆//原型对象叫做v1Video v1 = new Video("Java从入门到精通", date);Video v2 = (Video) v1.clone();System.out.println("v1原始的值:=====>"+v1);System.out.println("v2原始的值:=====>"+v2);//修改后的值,把date数值改变一下System.out.println("==================================");date.setTime(12345678);System.out.println("v1修改后的:=====>"+v1);System.out.println("v2修改后的:=====>"+v2);//
//
// System.out.println("v1.hashCode=====>"+v1.hashCode());
// //v1可以克隆v2
//
// System.out.println("v2=====>"+v2);
// System.out.println("v2.hashCode=====>"+v2.hashCode());
// //修改v2的值
// v2.setName("张三");
// System.out.println(v2);}
}
此时我们修改V1的值。上图所示,我们v1指向的是data。但是v2是v1克隆出来的。地址值是没有变化的。所以这是浅克隆。
测试结果:
我们理想的情况是:深度克隆
地址也会完全变化的。最简单的一种就是改造克隆的方法、修改原型类中的克隆方法实现深度克隆:
代码2:
java">package com.MrSun.PrototypeTest.demo02;import java.util.Date;public class Video implements Cloneable{private String name;private Date createTime;/*** 重写克隆方法* @return* @throws CloneNotSupportedException*/@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();//深度克隆Video v=(Video) obj;//将这个对象的属性也进行克隆v.createTime= (Date) this.createTime.clone();return obj;}public Video(String name, Date createTime) {this.name = name;this.createTime = createTime;}public Video() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "Video{" +"name='" + name + '\'' +", createTime=" + createTime +'}';}
}
主要就修改了cole方法
@Overrideprotected Object clone() throws CloneNotSupportedException {Object obj = super.clone();//深度克隆Video v=(Video) obj;//将这个对象的属性也进行克隆v.createTime= (Date) this.createTime.clone();return obj;}
我们对里面的属性也进行克隆。这样就可以实现深度克隆、
验证:
加油!!!!!!!!!!