1、概述
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
2、UML类图
3、代码示例
角色
- 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
- 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
- 访问类:使用具体原型类中的 clone() 方法来复制新的对象。
深拷贝和浅拷贝
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。注:Java中的Object类,提供了clone()方法来实现浅克隆。
抽象原型类
public interface Cloneable {
}
具体原型类
/**
* 人类
*/
public class People implements Cloneable {
private String name;
private Ticket ticket;
public People() {
}
public void show() {
System.out.println(name + "有" + ticket.getNum() + "张票。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Ticket getTicket() {
return ticket;
}
public void setTicket(Ticket ticket) {
this.ticket = ticket;
}
//浅拷贝:调用父类clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
//深拷贝:通过流进行序列化和反序列化
public Object deepCopy() throws IOException {
//输出流
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
//输入流
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//输出流
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//输入流
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
//转换成新的对象
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
assert bos != null;
bos.close();
assert oos != null;
oos.close();
assert bis != null;
bis.close();
assert ois != null;
ois.close();
}
return null;
}
}
访问类
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
//浅拷贝测试直接调用clone方法
try {
Ticket ticket = new Ticket();
ticket.setNum(8);
People people = new People();
people.setName("Andy");
people.setTicket(ticket);
People people1 = (People) people.clone();
people1.setName("tom");
people1.getTicket().setNum(5);
people.show();
people1.show();
System.out.println(people == people1);
} catch (Exception e) {
e.printStackTrace();
}
//深拷贝测试直接调用deepCopy方法,(调用比较简单不写了。)
}
}