Java学习之路4--原型模式(浅拷贝、深拷贝)

什么是原型模式

原型模式就是:
1.用原型实例指定创建对象的种类,并且通过克隆这些原型,创建新的对象。克隆创建的新对象中的原始值并不由构造函数决定,而是由被克隆的对象决定。
2.原型模式是一种创建型设计模式,运行一个对象再创建另外一个可定制的对象,无需知道如何创建的细节。
工作原理:
通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实现创建,即 对象.clone()。

浅拷贝的原型模式

题目

有一只羊hugo,姓名为 : hugo,年龄为 :2,颜色为 :蓝色,请编写程序创建和tom羊属性完全相同的10只羊。

传统实现

利用for循环与构造函数,对10只羊进行相同的数据赋值:

public Sheep(String name,int age,String color){
			this.name=name;
			this.age=age;
			this.color=color;
		}

for(int i=0;i<=9;i++)
		{
		Sheep hugo[i]=new Sheep("hugo",2,"blue");
		}

运用原型模式的浅克隆实现

通过实现Cloneable接口,将clone的protected改成public,再调用super.clone()。

//实现Cloneable接口,完成clone
		public Sheep clone() throws CloneNotSupportedException
		{
			//返回的是Object类型,要强制类型转换
			return (Sheep)super.clone();
		}
		
		for(int i=0;i<=9;i++)
		{
				Sheep a[i];
				try {
					a[i] = hugo.clone();
					System.out.println(a[i].toString());
				} catch (CloneNotSupportedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
		}

深拷贝的原型模式

1.什么是深拷贝

理解深拷贝之前,我们要先分清楚什么是引用数据类型,什么是值数据类型
值数据类型:就是像int,string等的8大基本数据类型。
引用数据类型:就是像对象、数组、可变变量这些数据类型。在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。

在浅拷贝中,我们的clone函数只能进行值数据类型的克隆,让值数据类型新建了属于自己的内存地址去保存。但是对于引用数据类型还是共用内存地址的。所以要进行深拷贝,必须要让引用数据类型新建一个内存地址去存储。

例子证明(运用浅拷贝进行引用数据的拷贝)

当数据类型为引用数据类型(以数组为例)时:

private String[] family=new String[3];
//在构造函数中初始化为father
family[0]="father";

进行浅拷贝:

public Deepsheep clone() throws CloneNotSupportedException
{
	//进行浅拷贝
	return (Deepsheep)super.clone();
}
System.out.println("hugo's father "+hugo.getfather());
System.out.println("a's father "+a.getfather());
a.tofamily("son");
System.out.println("hugo's father "+hugo.getfather());
System.out.println("a's father "+a.getfather());

输出:

hugo’s father father
a’s father father
hugo’s father son
a’s father son

从输出可以知道,当我们改变其中一个克隆对象的family[]数据时,其他的克隆对象包括本体一并改变了。说明他们都是共用一个存储内存,所以浅拷贝拷贝不了引用数据类型。当我们想对引用数据类型进行拷贝时,就要使用到深拷贝了。

2.怎么实现深拷贝

深拷贝实现方式1 :重写clone方法来实现深拷贝

//实现Cloneable接口,完成clone
public Deepsheep clone() throws CloneNotSupportedException
{
	//先进行浅拷贝
	Deepsheep sheep=null;
	sheep=(Deepsheep)super.clone();
	//再对引用数据类型进行单独实现拷贝方法
	sheep.family=(String[])family.clone();
	return sheep;
}

输出:

hugo’s father father
a’s father father
hugo’s father father
a’s father son

可以看到对其中一个对象进行更改不会影响到其他克隆对象,说明内存也重新分配了,达到了深拷贝的效果。
在对对象数据类型进行深拷贝时,要先在前一对象中实现浅/深拷贝,再在本层对象中进行调用来实现深拷贝。

深拷贝实现方式2 :通过对象序列化实现深拷贝

(后续再补)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值