创建型—原型模式-----掌握深复制
前言:
一个类创建多个实例;
实例内部 多数相同,且 实例的创建开销较大,输入较多的参数;
便可以使用 原型模式进行 简化操作
使用 原型实例 指定 创建对象的种类,并且通过赋值这些原型 创建新的对象
分为 浅复制 和 深复制
当 类成员属性中 为 基本数据类型(含String) 二者没什么不同;
当类成员属性中 为 引用数据类型, 浅复制 仅仅复制 原型对象的引用,就是相同的内存地址;
深复制 则是 将所有引用对象也复制;
利用构造函数 进行原型复制;
原理:
因为 复制操作依据 成员属性而变化,对基本数据类型没变化,仅仅是对 引用数据类型有变化;
因此 ,要对 引用数据类型 进行内部复制;
所以 要 建立一个自定义的构造方法,在引用数据类型和 被依赖类中构造;
//模板如下 Address(Address add) { super(); pro = add.getPro(); city = add.getCity(); zip = add.getZip(); }
package proto_creat;
public class Student_Create_Deep {
String name; //姓名
int age; //年龄
Address add; //籍贯
// 2类构造方式,第二个是 深复制需要的构造方法
Student_Create_Deep(String name, int age, Address add) {
super();
this.name = name;
this.age = age;
this.add = add;
}
Student_Create_Deep(Student_Create_Deep s){
name = s.getName();
age = s.getAge();
add = s.getAdd();
}
// Getter 和 Setter方法生成
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAdd() {
return add;
}
public void setAdd(Address add) {
this.add = add;
}
}
class Address{
String pro; //出生地
String city; //出生市
String zip; //出生地邮编
// Getter 和 Setter方法生成
public String getPro() {
return pro;
}
public void setPro(String pro) {
this.pro = pro;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
// 2类构造方式,第二个是 深复制需要的构造方法
public Address(String pro, String city, String zip) {
super();
this.pro = pro;
this.city = city;
this.zip = zip;
}
Address(Address add) {
super();
pro = add.getPro();
city = add.getCity();
zip = add.getZip();
}
}
package proto_creat;
public class Create_Test {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Address addr = new Address("liaoning","dalian","116081");
Student_Create_Deep s = new Student_Create_Deep("zhanglong",20,addr);
Student_Create_Deep s2 = new Student_Create_Deep(s);
System.out.println("s="+s+"\ts2"+s2);
System.out.println("s.name="+s.getName()+"\ts2.name="+s2.getName());
System.out.println("s.age="+s.getAge()+"\ts2.age="+s2.getAge());
System.out.println("s.add="+s.getAdd().getPro()+"\ts2.add="+s2.getAdd().getPro());
}
}
利用Cloneable接口方法
Java类都继承自 Object类;
Object类 提供一个 clone方法,可以将一个Java对象给复制;
但是 clone()方法是一个protected方法,外部类不能直接调用;
解决方案:
对于能够实现复制的Java类, 必须实现 一个 标识接口
Cloneable
,表示 这个Java类支持被复制;否则,调用clone()方法,Java编译器会抛出CloneNotSupportedException
异常
原理:同 利用构造函数一般,对 引用数据类型也加上Cloneable接口
该接口简单,没有定义任何方法,仅仅是起到一个标识作用,是一个空接口;
public class Student_Cloneable_Shallow implements Cloneable{
String name;
int age;
Address add; //这里会自动使用Student文件中的Address类;
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}