其他设计模式介绍
Java23种设计模式之单例模式总结
Java23种设计模式之工厂模式总结(简单工厂+工厂方法+抽象工厂)
Java23种设计模式之原型模式总结(浅克隆和深克隆)
Java23中设计模式之建造者模式总结
什么是原型模式? 克隆羊多利大家应该都知道,这其实可以理解为原型模式的一种体现即使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象!
原型模式分三个角色,抽象原型类,具体原型类,客户类。
抽象原型类(prototype): 它是声明克隆方法的接口,是所有具体原型类的公共父类,它可以是接口,抽象类甚至是一个具体的实现类。
具体原型类(concretePrototype): 它实现了抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的克隆对象。
客户类(Client): 在客户类中,使用原型对象只需要通过工厂方式创建或者直接NEW(实例化一个)原型对象,然后通过原型对象的克隆方法就能获得多个相同的对象。由于客户端是针对抽象原型对象编程的所以还可以可以很方便的换成不同类型的原型对象!
代码实现
public class Sheep {
private String name;
private int age;
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
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 class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("皮皮虾", 3);
Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge());
Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge());
System.out.println(sheep);
System.out.println(sheep1);
System.out.println(sheep2);
}
}
总结
Java中Object类是所有类地根类,Object类提供了一个clone()方法,该方法可以将一个Java对象复制一份,但是需要实现clone地Java类必须要实现一个接口Cloneable,该接口表示该类能够复制且具有复制地能力。
代码实现
public class Sheep implements Cloneable{
private String name;
private int age;
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
//重写clone方法
@Override
protected Object clone(){
Sheep sheep = null;
try {
sheep = (Sheep) super.clone();
}catch (Exception e) {
//打印出错误信息
System.out.println(e.getMessage());
}
return sheep;
}
}
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("皮皮虾", 3);
Sheep clone1 = (Sheep) sheep.clone(); //克隆
Sheep clone2 = (Sheep) sheep.clone();
System.out.println(sheep);
System.out.println(clone1);
System.out.println(clone2);
}
}
浅拷贝:我们只拷贝对象中的基本数据类型(8种),如果是复杂的类型,(枚举,String,对象)就只复制对应的内存地址。
public class Sheep implements Cloneable{
private String name;
private int age;
public Sheep friend; //对象
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
//重写clone方法(默认)
@Override
protected Object clone(){
Sheep sheep = null;
try {
sheep = (Sheep) super.clone();
}catch (Exception e) {
//打印出错误信息
System.out.println(e.getMessage());
}
return sheep;
}
}
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("皮皮虾", 3);
sheep.friend = new Sheep("皮皮虾2号",4);
Sheep clone1 = (Sheep) sheep.clone(); //克隆
Sheep clone2 = (Sheep) sheep.clone();
System.out.println(sheep + "friend:" + sheep.friend.hashCode());
System.out.println(clone1 + "friend:" + clone1.friend.hashCode());
System.out.println(clone2 + "friend:" + clone2.friend.hashCode());
}
}
运行结果
可以看见friend的hasCode是一样的,只是复制一份引用值继,进行引用传递,所以默认的clone方法是浅拷贝。
深拷贝:不仅能拷贝基本数据类型,还能拷贝那些数组、容器、引用对象等。
深拷贝有两种实现方式,一为重写clone方法,二为通过对象序列化(Serialization)来实现,我们这里选择使用更为推荐的对象序列化方式来进行实现。
public class Sheep implements Serializable {
private String name;
private int age;
//对象
private SheepFriend sheepFriend;
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Sheep(String name, int age, SheepFriend sheepFriend) {
this.name = name;
this.age = age;
this.sheepFriend = sheepFriend;
}
public SheepFriend getSheepFriend() {
return sheepFriend;
}
public void setSheepFriend(SheepFriend sheepFriend) {
this.sheepFriend = sheepFriend;
}
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;
}
//通过序列化和反序列化实现深拷贝
protected Sheep friendClone(){
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 (Sheep)ois.readObject();
}catch (Exception e) {
e.printStackTrace();
return null;
}finally {
//关闭流
try {
bos.close();
oos.close();
bis.close();
ois.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class SheepFriend implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SheepFriend(String name) {
this.name = name;
}
}
public class Client {
public static void main(String[] args) {
SheepFriend sheepFriend = new SheepFriend("Code皮皮虾");
Sheep sheep = new Sheep("皮皮虾", 3,sheepFriend);
Sheep sheep2 = sheep.friendClone();
System.out.println(sheep == sheep2);
System.out.println(sheep.getSheepFriend() == sheep2.getSheepFriend());
}
}
优点:
缺点:
觉得博主写的不错的读者大大们,可以点赞关注和收藏哦,谢谢各位!
博主更多博客文章