9、简单原型模式--深浅克隆!

原型模式(Protoype)
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.

之所以需要重写Cloneable的clone方法,因为方法访问修饰符是protected,外界没办法调用,这里用到[color=red]浅克隆[/color]


//原型
public class Prototype implements Cloneable{
private String name;
private String sex;
private String age;
private String timeArea;
private String company;

public String getName() {
return name;
}

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

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getTimeArea() {
return timeArea;
}

public void setTimeArea(String timeArea) {
this.timeArea = timeArea;
}

public String getCompany() {
return company;
}

public void setCompany(String company) {
this.company = company;
}

public Prototype(String name){
this.name = name;
}

//设置个人信息
public void SetPersonalInfo(String sex,String age){
this.sex = sex;
this.age = age;
};
//设置工作经历
public void SetWorkExperience(String timeArea,String company){
this.timeArea = timeArea;
this.company = company;
};
//显示
public void Display(){
System.out.println(name+"--年龄:"+age+"--性别:"+sex);
System.out.println("工作经历:"+timeArea+"--"+company);
}

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

入口main

public class Test {

public static void main(String[] args) throws Exception {
Prototype pro = new Prototype("小甜甜");
pro.SetPersonalInfo("女", "21");
pro.SetWorkExperience("2000-01-01", "天朝软件");

Prototype pro1 = (Prototype)pro.clone();
//一下输出,这不是同一个对象
//System.out.println(pro!=pro1);
pro1.SetPersonalInfo("男", "22");
pro1.SetWorkExperience("2000-01-01", "地府软件");

pro1.Display();
pro.Display();
}

}



以下引用Heart.X.Raid的Java深浅克隆
Java支持克隆

既然如此,难道我们就没有办法在某一个类的作用域外部来克隆这个类了吗?

答案是否定的! 我们可以在任何一个类中重写clone方法,并升级它的访问作用域。事实上,使用的时候也就是这样做的!

首先我们必须在需要克隆的类上实现一个重要的接口——Cloneable接口。这种接口我们叫作[color=red]标记接口[/color](tagging interface) 。这种标记接口没有任何方法,唯一的作用就是作为一个标志,用来告诉JVM一个类是否具有某个特定的功能。

如此一来,我们只要定义一个具有 Clone 功能的类就可以了:

[color=blue]1. 在类的声明中加入“ implements Cloneable ”,标志该类有克隆功能;
2. 重载类 Object 的 clone() 方法,在该方法中调用 super.clone() :[/color]

class Employee implements Cloneable{
public Object clone() throws CloneNotSupportedException{//重载clone()方法
Employee cloned=(Employee)super.clone();
return cloned;
}
}

class Employee implements Cloneable{
public Object clone() throws CloneNotSupportedException{//重载clone()方法
Employee cloned=(Employee)super.clone();
return cloned;
}
}

[color=darkred]深Clone和浅Clone[/color]
拷贝副本的问题并没有完全解决。clone技术并不是那么简单的。Object中的clone()方法是对具体类对象的各个域进行对应的赋值。如果具体类对象中还有子对象,这个问题就复杂了。

// 具备浅克隆的Employee类
class Employee implements Cloneable{
public String name="";
public Date hireDay=null;

public Object clone(){
Employee cloned=(Employee)super.clone();
return cloned;
}
}

Employee orignal=new Employee();
Employee copy=orignal.copy();

对于上面的代码,克隆以后orignal与copy中的hireDay指向的是同样的存储位置。也就是说当我们调用copy.hireDay.setTime()方法后,orignal中的hireDay也会发生改变。但String类(由于常量池的存储方式)和基本数据类型变量时不会改变的。这种对子对象克隆无效的方式我们叫做[color=red]浅克隆 [/color]。

很多情况下,我们需要将对象中的所有域(包括子对象)都进行真正的克隆。要做到这种深克隆,我们必须在重载clone()方法时克隆子对象:

//具备深度克隆功能的Employee类
class Employee implement Cloneable{
public String name="";
private Date hireDay=null;

public Object clone(){
Employee cloned=(Employee)super.clone(); //浅克隆
cloned.hireDay=(Date)hireDay.clone(); //克隆子对象
return cloned;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值