大家好,欢迎来到程序视点!
今天,我们一起来分享创建型模式的最后一个模式:原型模式
。
它的定义非常简单易懂。
用原型实例指定创建对象种类,并通过拷贝原型创建新的对象
通俗点的说法就是:照着原来的实例创建一个新对象
再通俗点:克隆一个对象实例
上面关于原型模式定义已经说的很明白了。在含义上没有其他需要特别说明的。
这里要注意的是Java中对这种模式的处理方式。
Java 中 Object 类是所有类的根类,Object 类提供了一个 clone 方法,该方法可以将一个 Java 对象复制一份,但是需要实现 clone 的 Java 类必须要实现一个接口 Cloneable,该接口表示该类能够复制且具有复制的能力
说了这么长一串,就是告诉大家:必须实现 Cloneable 接口
原型模式里有哪些角色呢?
来看看克隆羊的例子吧!
public class Sheep implements Cloneable {
private String name;
private Integer age;
private String color;
public Sheep(String name, Integer age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
... setter & getter
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
@Override
protected Object clone() {
Sheep sheep = null;
try {
sheep = (Sheep) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return sheep;
}
}
测试下:
public class Test {
public static void main(String[] args) {
Sheep sheep = new Sheep("Tom", 1, "白色");
for (int i = 0; i < 10; i++) {
// 克隆了10只羊
Sheep sheep1 = (Sheep) sheep.clone();
System.out.println(sheep1);
}
}
}
这里要说明两个要点:
所谓浅拷贝
,就是对象的成员属性是引用类型时,克隆后的新对象中的成员属性引用的依旧是原对象中成员属性的内存地址。也就是说:成员属性如果是引用类型,克隆的是内存地址;这个内存地址是不变的,指向的是同一个
如果对象的成员属性是基本数据类型,那默认就是值传递。也就是将该属性值复制一份给新的对象。
上面克隆羊的例子就是浅拷贝。
PS:这里有个特殊的引用类型类--String。String没有实现Cloneable,但它是“不可变的”,表现出来的是“深拷贝”的特性。
所谓深拷贝
,就是复制对象的所有基本数据类型的成员变量值,同时为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象。也就是说:全员复制
来个深拷贝的例子作为结尾。
public class Shepherd implements Cloneable {
private String name;
private int age;
private Sheep sheep;
... setter & getter
@Override
public Object clone() throws CloneNotSupportedException {
Shepherd shepherd = (Shepherd) super.clone();
// Sheep 需要实现 Cloneable, [强调]注意: Bag 这里只有基本数据类
// 如果要实现完全深拷贝, Shepherd类中只能含有非基本数据类型, 如果有非基本数据类, 那么在 sheep.clone()中必须再做一次类似的深拷贝复制
shepherd.setSheep((Sheep) this.sheep.clone());
return shepherd;
}
}
重点是 Shepherd 类中重写的 clone() 方法。Shepherd shepherd = (Shepherd) super.clone();
完成的就是浅拷贝。此次的 shepherd 对象中的 sheep 成员属性还引用的是原对象中的 sheep 的内存地址。
好在我们的 Sheep 也实现了 Cloneable 类。克隆一份 sheep 对象赋值回去就达到深拷贝的效果了。 于是就有shepherd.setSheep((Sheep) this.sheep.clone());
PS:关于深拷贝,可以细细体会下上面的这个示例。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有