设计模式——浅复制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>
结果为:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
简历深复制实现:
<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值 |
否 |
是 |
|
内存分配 |
分配在栈中 |
分配在堆中 |
|
主要职责 |
存储数据 |
传递引用(相当于指针) |
|
适用场合 |
该类型的共同拥有接口全然由一些数据成员存取属性定义; 永远不可能又子类。 不具有多态行为; |
具有多态行为; 用于定义应用程序的行为; |
浅复制和深复制含义
在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:
浅复制:
深复制:
通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="font-size:18px; font-family:KaiTi_GB2312; text-align:center">
小结
设计模式——浅复制VS深复制的更多相关文章
- 设计模式-原型模式(Prototype)【重点:浅复制与深复制】
讲故事 最近重温了一下星爷的<唐伯虎点秋香>,依然让我捧腹不已,幻想着要是我也能有一名秋香如此的侍女,夫复何求呀,带着这个美好的幻想沉沉睡去... 突然想到,我是一名程序猿呀,想要什么对象 ...
- iOS 浅复制和深复制的深层理解,含示例
转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...
- java基础-浅复制与深复制的理解
浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...
- iOS 浅复制、深复制、完全复制的知识点梳理验证(附加归档解档)
在之前转载的一片文章中,文中对浅复制和深复制进行了详细的解读,同时还提到了深复制(one-level-deep copy).完全复制(true copy)的概念,并指出iOS开发中的深复制是单层深赋值 ...
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...
- js中的浅复制和深复制
浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...
- 也来谈一谈js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...
随机推荐
- 信息竞赛程序卡时_C++
一.卡时简介 卡时是一个竞赛时常用的技巧 有些题目我们想不到完美算法就只能用暴力解决,但是此类方法一般时间复杂度较高,此时我们需要进行卡时 通俗来讲就是进行一个时间限制,让程序在达到这个时间后立马退出 ...
- penGL入门学习(六)
http://blog.csdn.net/sun6255028/article/details/5090067 今天要讲的是动画制作——可能是各位都很喜欢的.除了讲授知识外,我们还会让昨天那个“太阳. ...
- protobuf 中的嵌套消息的使用 主要对set_allocated_和mutable_的使用
protobuf的简单的使用,不过还留下了一个问题,那就是之前主要介绍的都是对简单数据的赋值,简单数据直接采用set_xx()即可,但是如果不是简单变量而是自定义的复合类型变量,就没有简单的set函数 ...
- js5秒后自动关闭本页面及5秒钟后自动跳转指定页面的方法
5秒钟后自动关闭 <!DOCTYPE HTML> <html> <head> <title>倒计时自动关闭/跳转页面</title> < ...
- Jquery实现下拉列表左右选择
知识点: jquery 的 click dbclick 事件 appendTo方法 <!DOCTYPE html> <html> <head> <met ...
- postgres 基本使用
postgres=# help 您正在使用psql, 这是一种用于访问PostgreSQL的命令行界面 键入: \copyright 显示发行条款 \h 显示 SQL 命令的说明 \? 显示 pgsq ...
- MVC 视图与控制器传值的几种方法
一.页面取值传给控制器 1.表单传值----利用Action 视图页: <form action="方法名" method="post" ...
- Parse error: syntax error, unexpected end of file in *.php on line * 解决方法
Parse error: syntax error, unexpected end of file in *.php on line * 解决方法 这篇文章主要介绍了PHP错误Parse erro ...
- java.util.List.subList ,开区间和闭区间
比如集合中的内容为1,2,3,4,5list.sublist(2,4)就返回一个子集合:它的内容包括从下标为2到下标为4,而且这是左闭右开的就是说是从大于等于2到小于4那子集内容就是3,4(集合的下标 ...
- 随机取若干条记录的SQL语句
原文:随机取若干条记录的SQL语句 MySql中随机提取数据库N条记录 select * from TableName order by rand() limit N SQLServer中随机提取 ...