设计模式创建型模式——原型模式(深复制VS浅复制)

浅复制:被复制对象的所有基本数据类型变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

深复制:被复制对象的所有基本数据类型变量都含有与原来的对象相同的值,并且引用对象的变量指向复制过的新对象,而不是原来被引用的对象。

下面,通过简历复制的例子来理解深复制和浅复制的概念

定义一个简历类Resume.java 实现Cloneable接口,并重新Object 类的clone()方法

public class Resume implements Cloneable{

    private String name;
    private String birthday;
    private String sex;
    private String school;

    private WorkExperience workExperience;

    /**
     * 构造函数
     * 初始化简历赋值姓名
     * 实例化工作经历
     */
    public Resume(String name){
        this.name = name;
        workExperience = new WorkExperience();
    }

    /**
     * @desc 设定个人基本信息
     * @param birthday 生日
     * @param sex 性别
     * @param school 毕业学校
     * @return void
     */
    public void setPersonInfo(String birthday,String sex,String school){
        this.birthday = birthday;
        this.sex = sex;
        this.school = school;
    }

    /**
     * @desc 设定工作经历
     * @param workDate 工作年限
     * @param company 所在公司
     * @return void
     */
    public void setWorkExperience(String workDate,String company){
        workExperience.setWorkDate(workDate);
        workExperience.setCompany(company);
    }

    /**
     * 克隆该实例
     */
    public Object clone(){
        Resume resume = null;
        try {
            resume = (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return resume;
    }

    public void display(){
        System.out.println("姓名:" + name);
        System.out.println("生日:" + birthday + ",性别:" + sex + ",毕业学校:" + school);
        System.out.println("工作年限:" + workExperience.getWorkDate() + ",公司:" + workExperience.getCompany());
    }
}

定义一个工作经历类WorkExperience.java用于封装工作经历。

public class WorkExperience {
    private String workDate;
    private String company;

    public String getWorkDate() {
        return workDate;
    }

    public void setWorkDate(String workDate) {
        this.workDate = workDate;
    }

    public String getCompany() {
        return company;
    }

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

客户端类Client.java

public class Client {

    public static void main(String[] args){
        //原型对象A
        Resume a = new Resume("小王");
        a.setPersonInfo("2.16", "男", "辽宁大学");
        a.setWorkExperience("2011.07.05", "辽宁科技有限公司");

        //克隆对象B
        Resume b = (Resume) a.clone();
        //修改B对象的个人信息
        b.setPersonInfo("8.19", "女", "河北大学");
        //修改B对象的工作经历
        b.setWorkExperience("2012.09.15","河北科技有限公司");

        //输出A和B对象
        System.out.println("----------------A--------------");
        a.display();
        System.out.println("----------------B--------------");
        b.display();

    }
}

运行结果

设计模式创建型模式——原型模式(深复制VS浅复制)_第1张图片

从结果中可以看到,克隆出来的B对象成功的修改了自己的个人信息,却没有修改A对象的个人信息;而B对象修改工作经历中的公司名称时,A对象中的公司名称也被修改了。

因为工作经历是一个引用类型,采用上述方法复制出来的B对象中的工作经历workexpericence变量是一个引用,它与A对象的引用指向同一个工作经历对象,因此修改B对象的工作经历A对象的工作经历也会改变。这便是浅复制的表现。

下面我们对刚刚的代码做一些修改。

修改工作经历类 WorkExperience.java,使其实现Cloneable接口,并重写Object的clone()方法

public class WorkExperience implements Cloneable {
    private String workDate;
    private String company;

    public String getWorkDate() {
        return workDate;
    }

    public void setWorkDate(String workDate) {
        this.workDate = workDate;
    }

    public String getCompany() {
        return company;
    }

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

    public Object clone(){
        WorkExperience workExperience = null;
            try {
                workExperience = (WorkExperience) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return workExperience;
        }
}

在简历类Resume.java的clone()方法中,添加一行调用WorkExperience的clone()方法的代码

public class Resume implements Cloneable{

    private String name;
    private String birthday;
    private String sex;
    private String school;

    private WorkExperience workExperience;

    /**
     * 构造函数
     * 初始化简历赋值姓名
     * 实例化工作经历
     */
    public Resume(String name){
        this.name = name;
        workExperience = new WorkExperience();
    }

    /**
     * @desc 设定个人基本信息
     * @param birthday 生日
     * @param sex 性别
     * @param school 毕业学校
     * @return void
     */
    public void setPersonInfo(String birthday,String sex,String school){
        this.birthday = birthday;
        this.sex = sex;
        this.school = school;
    }

    /**
     * @desc 设定工作经历
     * @param workDate 工作年限
     * @param company 所在公司
     * @return void
     */
    public void setWorkExperience(String workDate,String company){
        workExperience.setWorkDate(workDate);
        workExperience.setCompany(company);
    }

    /**
     * 克隆该实例
     */
    public Object clone(){
        Resume resume = null;
        try {
            resume = (Resume) super.clone();
            this.workExperience = (WorkExperience)workExperience.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return resume;
    }

    public void display(){
        System.out.println("姓名:" + name);
        System.out.println("生日:" + birthday + ",性别:" + sex + ",毕业学校:" + school);
        System.out.println("工作年限:" + workExperience.getWorkDate() + ",公司:" + workExperience.getCompany());
    }
}

客户类Client.java不做改动

运行结果

设计模式创建型模式——原型模式(深复制VS浅复制)_第2张图片

分析结果可知,我们修改了B对象的工作经历对A对象并未产生影响。这便是深复制的表现。

(声明:本文为个人学习笔记,观点非原创。如有问题,欢迎讨论。)

你可能感兴趣的:(设计模式)