原型模式-(clone,浅克隆与深克隆)

原型模式(克隆)

  • Prototype

  • 拷贝与复制

    • IO流当然也可以实现拷贝,但是效率不如在内存中实现拷贝。

      问题是,Java直接操作内存是比较麻烦的,就得将这部分工作交给C/C++。关键字native

    • Object类中的clone()方法,Cloneable接口。

  • 实现方法:

    1. 实现Cloneable接口
    2. 重写clone方法。

浅克隆

  • 存在一个属性指向相同的内存空间(如Date属性),当一个对象修改该属性值的时候,另一个对象中的该属性也发生了变化。虽然对象之间是完全不同的(从hashcode可以看出,他们是完全不同的两个对象),但是他们的某些属性可能指向了相同的空间(可能默写属性的引用相同)。

image-20200422104406047

原型类

package com.tiko.prototype.demo1;

import java.util.Date;

public class VideoProto implements Cloneable {

	private String name;
	private Date date;

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	public VideoProto() {
	}

	public VideoProto(String name, Date date) {
		this.name = name;
		this.date = date;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	@Override
	public String toString() {
		return "VideoProto{" +
				"name='" + name + '\'' +
				", date=" + date +
				'}';
	}
}

测试

package com.tiko.prototype.demo1;

import java.util.Date;

public class Client {

	public static void main(String[] args) throws CloneNotSupportedException {

		//原型对象
		Date date = new Date();
		VideoProto v1 = new VideoProto("视频原型", date);
		System.out.println("v1:"+v1);
		System.out.println("v1:hash"+v1.hashCode());

		//通过克隆创建新对象
		VideoProto v2 = (VideoProto)v1.clone();//克隆出来的对象和原来是一样的
		System.out.println("v2:"+v2);
		System.out.println("v2:hash"+v2.hashCode());

		System.out.println("通过clone对象修改属性...");//通过输出结果可以看出这是浅克隆(浅拷贝)
		date.setTime(213413412);

		System.out.println("v1:"+v1);
		System.out.println("v1:hash"+v1.hashCode());

		System.out.println("v2:"+v2);
		System.out.println("v2:hash"+v2.hashCode());
	}
}
//程序输出
v1:VideoProto{name='视频原型', date=Wed Apr 22 10:42:09 CST 2020}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:42:09 CST 2020}
v2:hash325040804
通过clone对象修改属性...
v1:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v2:hash325040804

深克隆

  • 对象是完全不同的两个东西。(除了对象的类型是相同的,对象中的属性是完全的不同的。八竿子打不着的关系)

image-20200422104724694

原型类

package com.tiko.prototype.demo2;

import java.util.Date;

public class VideoProto implements Cloneable {

	private String name;
	private Date date;

	@Override
	protected Object clone() throws CloneNotSupportedException {
		 //实现深克隆
		Object clone = super.clone();

		//先向下转型为VideoProto
		 VideoProto v = (VideoProto) clone;
		 //clone对象的属性值接受被克隆对象的属性值。->完成对象的属性的克隆
		v.date = (Date) this.date.clone();//this,指向调用者,即被克隆对象

		return v;//返回clone对象
	}

	public VideoProto() {
	}

	public VideoProto(String name, Date date) {
		this.name = name;
		this.date = date;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	@Override
	public String toString() {
		return "VideoProto{" +
				"name='" + name + '\'' +
				", date=" + date +
				'}';
	}
}

深克隆实现

	@Override
	protected Object clone() throws CloneNotSupportedException {
		 //实现深克隆
		Object clone = super.clone();

		//先向下转型为VideoProto
		 VideoProto v = (VideoProto) clone;
		 //clone对象的属性值接受被克隆对象的属性值。->完成对象的属性的克隆
		v.date = (Date) this.date.clone();//this,指向调用者,即被克隆对象

		return v;//返回clone对象
	}

测试

package com.tiko.prototype.demo2;

import java.util.Date;

public class Client {

	public static void main(String[] args) throws CloneNotSupportedException {

		//原型对象
		Date date = new Date();
		VideoProto v1 = new VideoProto("视频原型", date);
		System.out.println("v1:"+v1);
		System.out.println("v1:hash"+v1.hashCode());

		//通过克隆创建新对象
		VideoProto v2 = (VideoProto)v1.clone();//克隆出来的对象和原来是一样的
		System.out.println("v2:"+v2);
		System.out.println("v2:hash"+v2.hashCode());

		System.out.println("通过clone对象修改属性...");//通过输出结果可以看出这是深克隆(深拷贝)
		date.setTime(213413412);

		System.out.println("v1:"+v1);
		System.out.println("v1:hash"+v1.hashCode());

		System.out.println("v2:"+v2);
		System.out.println("v2:hash"+v2.hashCode());
	}
}

//结果输出
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:48:46 CST 2020}
v2:hash325040804
通过clone对象修改属性...
v1:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:48:46 CST 2020}
v2:hash325040804

参考自狂神说Java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值