原型模式
原型模式是一种创建型设计模式,它允许通过复制一个已有的对象来创建新的对象,而无需知道具体的类别。原型模式通过实现Cloneable接口,并重写clone()方法,在运行时动态地创建一个与原型对象相同的新对象。
在原型模式中,每个原型对象都可以被视为一个模板或蓝图,用于生成新的对象。当需要创建新的对象时,通过复制这个模板对象并修改其中的属性值,就可以快速地创建出一个全新的对象,而不必重新创建和初始化对象,从而提高了代码的效率和可维护性。
原型模式通常分为深拷贝和浅拷贝两种类型。浅拷贝是指只复制基本数据类型和对象的引用,而不复制对象本身,因此多个对象可能会共享同一个引用,从而导致意外的副作用。深拷贝则是在复制对象时递归复制对象的所有子对象,并创建新的对象实例来存储复制的内容,从而确保每个对象都是独立的,互不干扰。
深拷贝:创建一个新的对象,属性中引用其他对象也会被克隆,不再指向原有对象地址
浅拷贝:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
案例1.1
Person类,其中包含了姓名和出生日期两个属性:
/**
* Person实现Cloneable接口,并重写了clone()方法以支持对象的复制。
* */
public class Person implements Cloneable {
private String name;
private Date birthDate;
public Person(String name, Date birthDate) {
this.name = name;
this.birthDate = birthDate;
}
public void setName(String name) {
this.name = name;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getName() {
return name;
}
public Date getBirthDate() {
return birthDate;
}
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
在主函数中,我们可以创建一个原型对象并通过调用clone()方法来创建新的对象:
// 创建原型对象
Person person1 = new Person("张三", new Date());
// 使用克隆方法创建新的对象
Person person2 = person1.clone();
// 修改person2的属性值,不影响person1
person2.setName("李四");
person2.setBirthDate(new Date(2020, 1, 1));
System.out.println(person1 == person2);
System.out.println(person1);
System.out.println(person2);
赋值之后 拷贝出来的结果 (地址值不一样)
```
// 创建原型对象
Person person1 = new Person("张三", new Date());
// 使用克隆方法创建新的对象
Person person2 = person1.clone();
// 修改person2的属性值,不影响person1
// person2.setName("李四");
// person2.setBirthDate(new Date(2020, 1, 1));
System.out.println(person1 == person2);
System.out.println(person1);
System.out.println(person2);
System.out.println(person1.getName().equals( person2.getName()));
System.out.println(person1.getName());
System.out.println(person2.getName());
System.out.println(person1.getBirthDate() == person2.getBirthDate());
System.out.println(person1.getBirthDate());
System.out.println(person2.getBirthDate());
```
不赋值 拷贝出来的结果 (不同对象,地址值不一样,属性一样)
浅拷贝 学生案例
public class Student implements Cloneable {
private String name;
private int[] scores;
public Student(String name, int[] scores) {
this.name = name;
this.scores = scores;
}
public void setName(String name) {
this.name = name;
}
public void setScores(int[] scores) {
this.scores = scores;
}
public String getName() {
return name;
}
public int[] getScores() {
return scores;
}
@Override
public Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
// 创建原型对象
Student student1 = new Student("张三", new int[]{90, 85, 95});
// 浅拷贝
Student student2 = (Student) student1.clone();
student2.setName("李四");
student2.getScores()[0] = 100;
// 输出结果
System.out.println(student1.getName() + " " + Arrays.toString(student1.getScores())); // 张三 [100, 85, 95]
System.out.println(student2.getName() + " " + Arrays.toString(student2.getScores())); // 张三 [100, 85, 95]
}
上边案例可以看出 对象中引用对象地址值是一样的
深拷贝 学生案例
在学生类中 修改这一行代码