背景
古铁工厂在研究如何快速复制古铁机体,已经有了突破性的进展。复制分为两种方式,一种只是复制外观,电脑里面存储的信息还是共享的,会导致古铁的一些记录如击坠数会被复制古铁改变(浅拷贝)。另一种是完全复制,复制双方互不影响。(深拷贝)
实现
古铁
/**
* 古铁
*/
public class AncientIron implements Cloneable {
private String color;
private String height;
private String weight;
private RobotInfo info;
public AncientIron(String color, String height, String weight,
RobotInfo info) {
super();
this.color = color;
this.height = height;
this.weight = weight;
this.info = info;
}
/**
* 浅拷贝
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* 深拷贝
* @return
* @throws CloneNotSupportedException
*/
protected Object deepClone() throws CloneNotSupportedException {
AncientIron obj = (AncientIron) super.clone();
obj.setInfo((RobotInfo) obj.getInfo().clone());
return obj;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public RobotInfo getInfo() {
return info;
}
public void setInfo(RobotInfo info) {
this.info = info;
}
@Override
public String toString() {
return "AncientIron [color=" + color + ", height=" + height
+ ", weight=" + weight + ", info=" + info + "]";
}
}
机体信息
/**
* 机体信息:存储在操作系统里面
*/
public class RobotInfo implements Cloneable {
private String produceTime; // 生产日期
private String repairCount; // 维修次数
private String killCount; // 击杀数
public RobotInfo(String produceTime, String repairCount, String killCount) {
super();
this.produceTime = produceTime;
this.repairCount = repairCount;
this.killCount = killCount;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getProduceTime() {
return produceTime;
}
public void setProduceTime(String produceTime) {
this.produceTime = produceTime;
}
public String getRepairCount() {
return repairCount;
}
public void setRepairCount(String repairCount) {
this.repairCount = repairCount;
}
public String getKillCount() {
return killCount;
}
public void setKillCount(String killCount) {
this.killCount = killCount;
}
@Override
public String toString() {
return "RobotInfo [produceTime=" + produceTime + ", repairCount="
+ repairCount + ", killCount=" + killCount + "]";
}
}
测试
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
RobotInfo info = new RobotInfo("2019-01-01", "11", "100");
AncientIron ancientIron = new AncientIron("红色","56m","10t",info);
// 浅拷贝:修改克隆对象的引用属性会影响原对象
AncientIron cloneAncientIron = (AncientIron) ancientIron.clone();
System.out.println(cloneAncientIron);
System.out.println(ancientIron);
// 修改了引用属性,原对象改变了
cloneAncientIron.setColor("钢琴黑");
cloneAncientIron.getInfo().setKillCount("101");
System.out.println(cloneAncientIron);
System.out.println(ancientIron);
System.out.println("-----我是分界线-----------");
// 深拷贝:全部拷贝过来,修改互不影响
AncientIron cloneAncientIron2 = (AncientIron) ancientIron.deepClone();
System.out.println(cloneAncientIron2);
System.out.println(ancientIron);
// 修改了引用属性,原对象不变
cloneAncientIron2.setColor("蔷薇紫");
cloneAncientIron2.getInfo().setKillCount("102");
System.out.println(cloneAncientIron2);
System.out.println(ancientIron);
}
}
测试结果
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=100]]
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=100]]
AncientIron [color=钢琴黑, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=101]]
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=101]]
-----我是分界线-----------
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=101]]
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=101]]
AncientIron [color=蔷薇紫, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=102]]
AncientIron [color=红色, height=56m, weight=10t, info=RobotInfo [produceTime=2019-01-01, repairCount=11, killCount=101]]
总结
原型模式应用面很窄,需要实现Clonable接口,用来标识该对象可以复制。复制又分为深拷贝和浅拷贝。
浅拷贝:不会复制引用类型,故修改引用值会影响原对象
深拷贝:修改互不影响。