原型模式

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

解释:我有一幅《清明上河图》的原画卷(原型实例),我通过复印机复印这幅原画卷得到了新的画卷(新的对象)。

// 画家
public class Painter{

	// 姓名
	private String name;

	public String getName(){
		return this.name;
	}

	public void setName(String name){
		this.name = name;
	}
}
/* 画卷:实现 Cloneable 接口.
(1)Cloneable是一个标记接口,没有任何方法。
(2)类似 Cloneable 的还有:RandomAccess(集合快速访问)、Serializable (序列化)。
(3)它们的作用就是当某个类实现这个接口时,我们就认为这个类拥有了接口标记的某种功能。
(4)java.lang.Object 本就有 clone() 方法(如下):
protected native Object clone() throws CloneNotSupportedException; 
但若没实现 Cloneable 标记接口,也会抛出 CloneNotSupportedException 异常。
注:native方法是非Java代码实现的方法。
*/
public class PictureScroll implements Cloneable{

	// 画长
	private String length;
	
	// 画宽
	private String width;

	// 画家
	private Painter painter;

	// 省略 getter / setter

	// 实现clone()方法实现浅克隆
	public PictureScroll clone(){
		try {
			Object obj = super.clone();
			return (PictureScroll)obj;
		} catch (CloneNotSupportedException e) {
			return null;
		}
	}
}
/**
 * A class implements the <code>Cloneable</code> interface to
 * indicate to the {@link java.lang.Object#clone()} method that it
 * is legal for that method to make a
 * field-for-field copy of instances of that class.
 * 
 * (译):类实现 Cloneable接口,以向 clone() 方法指示该方法为该类的实例拷贝字段是合法的。
 * ...
 */
public interface Cloneable {
}
// 测试
public class Test{
	public static void main(String[] args){

		PictureScroll originalPictureScroll = new PictureScroll();
		Painter painter = new Painter();
		painter.setName("张择端");
		originalPictureScroll.setPainter(painter);
		originalPictureScroll.setWidth("24.8厘米");
		originalPictureScroll.setLength("528.7厘米");

		// 用原型实例(originalPictureScroll)指定创建对象的种类,并且通过拷贝这些原型创建新的对象(copyPictureScroll)。
		PictureScroll copyPictureScroll = originalPictureScroll.clone();
		System.out.println("画家:" + copyPictureScroll.getPainter().getName() + 
			";宽:" + copyPictureScroll.getWidth() + 
			";长:" + copyPictureScroll.getLength()); 
			// 画家:张择端;宽:24.8厘米;长:528.7厘米

		System.out.println(originalPictureScroll == copyPictureScroll); // false
		System.out.println(originalPictureScroll.getPainter() == copyPictureScroll.getPainter()); // true
	}
}

注意区分浅克隆/深克隆(或者说 浅拷贝/深拷贝浅复制/深复制)。

java.lang.Object 提供了一个对象拷贝的默认方法 clone 方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:
1、基本类型
如果变量是基本类型,则拷贝其值,比如:int、float、long等。
2、String字符串
这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为 String 是个基本类型。
3、对象
如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在 Java 中很疯狂,因为它突破了访问权限的定义,一个 private 修饰的变量,竟然可以被两个实例对象访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值