指原型实例指定创建对象的种类,并且通过拷贝这些原型创建一个新的对象
换句话讲就是我们通常所说的复制粘贴,这就是原型模式的思想
被克隆的对象实现Cloneable接口
重写clone方法调用父类的clone方法
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Product4 product4 = new Product4("part1", "part2", "part3", 1, 2,baseInfo);
Product4 clone = product4.clone();
//输出两个不同的对象
System.out.println(product4);
System.out.println(clone);
}
}
//被克隆的类
class Product4 implements Cloneable{
private String part1;
private String part2;
private String part3;
private Integer part4;
private Integer part5;
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public String getPart3() {
return part3;
}
public void setPart3(String part3) {
this.part3 = part3;
}
public Integer getPart4() {
return part4;
}
public void setPart4(Integer part4) {
this.part4 = part4;
}
public Integer getPart5() {
return part5;
}
public void setPart5(Integer part5) {
this.part5 = part5;
}
public BaseInfo getBaseInfo() {
return baseInfo;
}
public void setBaseInfo(BaseInfo baseInfo) {
this.baseInfo = baseInfo;
}
public Product4(String part1, String part2, String part3, Integer part4, Integer part5, BaseInfo baseInfo) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.part4 = part4;
this.part5 = part5;
this.baseInfo = baseInfo;
}
@Override
public String toString() {
return "["+super.hashCode()+"]Product4{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3='" + part3 + '\'' +
", part4=" + part4 +
", part5=" + part5 +
'}';
}
//重写clone()方法
@Override
protected Product4 clone() throws CloneNotSupportedException {
return ((Product4)super.clone());
}
}
只拷贝对象中的基本数据类型(8种),对于数组,容器引用对象等不会考贝
不仅能拷贝基本数据类型,还能拷贝数组,容器,引用对象等
在拷贝对象的属性中添加一个引用对象属性。然后修改引用对象属性
引用对象
//被引用对象
class BaseInfo implements Cloneable{
private String companyName;
@Override
public String toString() {
return "["+super.hashCode()+"]BaseInfo{" +
"companyName='" + companyName + '\'' +
'}';
}
@Override
protected BaseInfo clone() throws CloneNotSupportedException {
return ((BaseInfo) super.clone());
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public BaseInfo(String companyName) {
this.companyName = companyName;
}
}
在拷贝对象的属性中添加引用对象
private String part1;
private String part2;
private String part3;
private Integer part4;
private Integer part5;
private BaseInfo baseInfo;
查看结果
public static void main(String[] args) throws CloneNotSupportedException {
BaseInfo baseInfo = new BaseInfo("aaa");
Product4 product4 = new Product4("part1", "part2", "part3", 1, 2,baseInfo);
Product4 clone = product4.clone();
System.out.println(product4);
System.out.println(clone);
//修改引用对象
baseInfo.setCompanyName("bbb");
//显示修改后的内容
System.out.println(product4);
System.out.println(clone);
}
显示修改后的内容,这显然是不可取的
为什么拷贝的对象,引用类型会是同一个呢?
被拷贝对象的引用对象指向一个内存地址a,拷贝对象拷贝后引用类型也指向地址a所以是同一个对象
那么如何解决呢?
将拷贝对象引用类型的值设置成被拷贝对象引用类型的克隆
引用对象实现Cloneable接口重写clone方法
//被引用对象
class BaseInfo implements Cloneable{
private String companyName;
@Override
public String toString() {
return "["+super.hashCode()+"]BaseInfo{" +
"companyName='" + companyName + '\'' +
'}';
}
//重写clone方法
@Override
protected BaseInfo clone() throws CloneNotSupportedException {
return ((BaseInfo) super.clone());
}
}
被克隆对象重写clone方法
//重写clone方法
//将拷贝对象引用类型的值设置成被拷贝对象引用类型的克隆
@Override
protected Product4 clone() throws CloneNotSupportedException {
Product4 clone = (Product4) super.clone();
BaseInfo clone1 = this.baseInfo.clone();
clone.setBaseInfo(clone1);
return clone;
}
当我们的类初始化需要消耗很多的资源时,就可以使用原型模式,因为我们的克隆不会执行构造方法,避免了初始化占有的时间和空间
一个对象被其他对象访问,并且能够修改时,访问权限都无效了,什么都能修改