プロトタイプモード:プロトタイプインスタンスを使用して、作成するオブジェクトのタイプを指定し、これらのプロトタイプをコピーして新しいオブジェクトを作成します。
プロトタイプモードでは、作成の詳細を知らなくても、1つのオブジェクトから別のカスタマイズ可能なオブジェクトを作成できます。
浅いコピー、深いコピー
浅いコピー、実数のタイプフィールドの値をコピーします。実ドメイン参照型参照オブジェクトは、参照のみを複製しません。つまり、複製されたオブジェクト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'}