zoukankan      html  css  js  c++  java
  • 设计模式——浅复制VS深复制

    背景

       在学习原型模式的时候,採用了一个差别与其它模式的新方法。採用了“克隆(Clone)方法。通过实现ICloneable接口中的Clone()方法来达到克隆的目的。

    代码实现过程中,存在了我们所说的浅复制和深复制,以下看看有什么差别。

    内容

    代码实现

    简历浅复制实现:

    <span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace 浅复制
    {
        class Program
        {
            static void Main(string[] args)
            {
                Resume a = new Resume("大鸟");
                a.SetPersonalInfo("男", "29");
                a.SetWorkExperience("1992-2002", "XX公司");
    
                Resume b = (Resume)a.Clone();
                b.SetWorkExperience ("1992-2002","YY公司");
    
                Resume c=(Resume )a.Clone ();
                c.SetPersonalInfo ("男","24");
                c.SetWorkExperience ("1995-2200","ZZ企业");
    
                a.Display ();
                b.Display ();
                c.Display ();
                Console .Read ();
            }
        }
        //工作经历类
        class WorkExperience
        {
            private string workDate;
            public string WorkDate
            {
                get { return workDate; }
                set { workDate = value; }
            }
    
            private string company;
            public string Company
            {
                get { return company; }
                set { company = value; }
    
            }
    
        }
    
        //简历类
        class Resume:ICloneable
        {
            private string name;
            private string sex;
            private string age;
    
            private WorkExperience work;//引用“工作经历”对象
    
            public Resume (string name )
            {
                this.name = name;
                work = new WorkExperience();//在“简历”类实例化时间时实例化“工作经历”;
            }
            //设置个人信息
            public void SetPersonalInfo(string sex, string age)
            {
                this.sex =sex ;
                this .age =age ;
    
            }
    
            //设置工作经历
            public void SetWorkExperience (string workDate,string company)
            {
                //调用此方法时,给对象的两属性赋值;
                work.WorkDate = workDate;
                work.Company = company;
            }
            //显示
            public void Display()
            {
                Console.WriteLine("{0} {1} {2}", name, sex, age);
                Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);//显示时,显示“工作经历”的两属性的值。

    } public Object Clone() { return (Object)this.MemberwiseClone(); } } } </span></span>

    结果为:
               

    简历深复制实现:

    <span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">//作者:周丽同
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace 简历的深复制实现
    {
        class Program
        {
            static void Main(string[] args)
            {
                Resume a = new Resume("大鸟");
                a.SetPersonalInfo("男", "29");
                a.SetWorkeExperience("1998-2000", "XX公司");
    
                Resume b = (Resume)a.Clone();
                b.SetWorkeExperience("1998-2006", "YY公司");
    
                Resume c = (Resume)a.Clone();
                c.SetPersonalInfo("男", "24");
                c.SetWorkeExperience("1998-2003", "ZZ企业");
    
                a.Display();
                b.Display();
                c.Display();
    
                Console.Read();
            }
        }
    
        //修改的地方是:让工作经历也实现ICloneable接口
        //工作经历类
        class WorkExperience:ICloneable
        {
            private string workDate;
            public string WorkDate
            {
                get { return workDate; }
                set { workDate = value; }
            }
            private string company;
            public string Company
            {
                get { return company; }
                set { company = value; }
            }
    
            public Object Clone()
            {
                return (Object)this.MemberwiseClone();//“工作经历”类实现克隆方法。
            }
        }
    
        //简历类
        class Resume:ICloneable
        {
            private string name;
            private string sex;
            private string age;
            private WorkExperience work;
    
            public Resume (string name)
            {
                this.name = name;
                work = new WorkExperience();
            }
            private Resume (WorkExperience work)
            {   
                //提供克隆(Clone)方法调用的私有构造函数,以便克隆“工作经历”的数据;
                this.work = (WorkExperience)work.Clone();
    
            }
    
            //设置个人信息
            public void SetPersonalInfo(string sex,string age )
            {
                this.sex = sex;
                this.age = age;
            }
            //设置工作经历
    
            public void SetWorkeExperience(string workDate,string company)
            {
                work.WorkDate = workDate;
                work.Company = company;
            }
            //显示
    
            public void Display()
            {
                Console.WriteLine("{0} {1} {2}", name, sex, age);
                Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
            }
    
            public Object Clone()
            {
                //调用私有的构造函数,让“工作经历”克隆完毕。然后再给这个“简历”对象的相关字段赋值。
                //终于返回一个深复制的简历对象。
                Resume obj = new Resume(this.work);
                obj.name = this.name;
                obj.sex = this.sex;
                obj.age = this.age;
                return obj;
            }
        }
    
    }</span></span>

    结果是:                                   

                                              

       从上面的样例能够看出为什么对于值类型的对象。在克隆的时候能够轻易的复制过来,可是对于引用类型的。在克隆的时候复制过来的仅仅是引用对象,而引用对象的数据是不会复制过来的。这里涉及到了什么是值类型和引用类型。它们在内存中是怎么“走的”。且看且分析:

     

    值类型

    引用类型

    类型

    结构体;数值类型(整型);浮点型。decimal型;bool型;枚举;可空类型;

    数组。用户定义的类。接口;托付; Object类型;字符串类型;

    能否够包括null值

    内存分配

    分配在栈中

    分配在堆中

    主要职责

    存储数据

    传递引用(相当于指针)

    适用场合

    该类型的共同拥有接口全然由一些数据成员存取属性定义;

    永远不可能又子类。

    不具有多态行为;

    具有多态行为;

    用于定义应用程序的行为;

    浅复制和深复制含义

       在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:

    浅复制:

                                                                                                       

    深复制:

                                                                                                     

       通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是: 

    小结

       以上是本人关于c#中浅复制和深复制的一些理解。自己的理解还是有点表面。多多实践样例就会好非常多,望各路大神提出宝贵意见。
    1、不要害怕自己的想法不正确,对不正确试试就知道了。

    2、学会站在巨人的肩膀上。
    3、相信自己。


    感谢您的宝贵时间~~~
  • 相关阅读:
    关于web测试收集
    Webdriver初探
    Java学习笔记 11/15:一个简单的JAVA例子
    持续集成环境搭建总结
    启动速度
    excel中用到的函数
    jmerter使用
    接口测试
    内存泄漏场景
    手机连接电脑那些事
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7400750.html
Copyright © 2011-2022 走看看