原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
浅复制,深复制
浅复制,复制值类型的实域,对引用类型的实域只复制引用不复制引用的对象,即克隆出来的对象b
和原对象a
引用同一个对象类型的实域c
,在 b的方法
改变 b中的c
会影响 a中的c
。
//简历类,实现Cloneable接口
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private String time;
private String company;
public Resume(String name) {
this.name = name;
}
public void SetInfo(String sex, String age) {
this.sex = sex;
this.age = age;
}
public void SetWork(String time, String company) {
this.time = time;
this.company = company;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
@Override
public String toString() {
return "Resume{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
", time='" + time + '\'' +
", company='" + company + '\'' +
'}';
}
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume1 = new Resume("RagdoLL");
resume1.SetInfo("man", "21");
resume1.SetWork("2022", "Ubisoft");
Resume resume2 = (Resume) resume1.clone();
System.out.println(resume1.toString());
System.out.println(resume2.toString());
}
}
输出:
Resume{name='RagdoLL', sex='man', age='21', time='2022', company='Ubisoft'}
Resume{name='RagdoLL', sex='man', age='21', time='2022', company='Ubisoft'}
如果改为对象 Work
持有time
和 company
实域,浅复制无法完成引用对象的复制,只复制了引用
//简历类,实现Cloneable接口
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private Work work;
public Resume(String name) {
this.name = name;
work = new Work();
}
public void SetInfo(String sex, String age) {
this.sex = sex;
this.age = age;
}
public void SetWork(String time, String company) {
this.work.setTime(time);
this.work.setCompany(company);
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
@Override
public String toString() {
return "Resume{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
", time='" + work.getTime() + '\'' +
", company='" + work.getCompany() + '\'' +
'}';
}
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume1 = new Resume("RagdoLL");
resume1.SetInfo("man", "21");
resume1.SetWork("2022", "Ubisoft");
Resume resume2 = (Resume) resume1.clone();
resume2.SetWork("2021","Action");
System.out.println(resume1.toString());
System.out.println(resume2.toString()); //改变resume2的Work,resume1的Work对象的值被覆盖
}
}
深复制,对引用对象Work
也进行复制。
//简历类,实现Cloneable接口
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private Work work;
public Resume(String name) {
this.name = name;
work = new Work();
}
//克隆引用对象的接口
public void setWork(Work work) {
this.work = work;
}
public void SetInfo(String sex, String age) {
this.sex = sex;
this.age = age;
}
public void SetWork(String time, String company) {
this.work.setTime(time);
this.work.setCompany(company);
}
@Override
protected Resume clone() throws CloneNotSupportedException {
//这一步还是浅克隆
Resume resume = (Resume) super.clone();
//完成深克隆
resume.setWork((Work) work.clone());
return resume;
}
@Override
public String toString() {
return "Resume{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
", time='" + work.getTime() + '\'' +
", company='" + work.getCompany() + '\'' +
'}';
}
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume1 = new Resume("RagdoLL");
resume1.SetInfo("man", "21");
resume1.SetWork("2022", "Ubisoft");
Resume resume2 = resume1.clone();
resume2.SetWork("2021", "Action");
System.out.println(resume1.toString());
System.out.println(resume2.toString());
}
}
输出:
Resume{name='RagdoLL', sex='man', age='21', time='2022', company='Ubisoft'}
Resume{name='RagdoLL', sex='man', age='21', time='2021', company='Action'}