【转】也说值类型和引用类型
【http://www.cnblogs.com/zhhh/archive/2011/12/28/2305358.html】
初接触编程,确实感觉它抽象,而且很多时候觉得抽象的让人蛋疼。
以变量为例,最初还只是简单的数值,这很容易让人理解。可自面向对象思想流行以后,变量又引入了引用类型。突然之间,许多人又开始蛋疼起来。
其实,对变量而言,变量只是变量,引用类型的变量只是在使用变量存取数值的时候进行了一些稍复杂一点的处理——从以前的直接取值到从其值所表示的内存地址找相应的对象取值。
打个比方,将我作为一个主体。
//我的年龄是多少?
MyAge=24
//我的体重是多少?
MyWeight=70
//我的上衣是什么颜色?
TheColorOfMyJacket=黑色
这是值类型,很简单,很早以前我们在小学数学里就接触过了。比如a=1,b=2,a+b就等于3,一个意思。
后来,引用面向对象思想以后。世界变了,变的简单了,也变的让人蛋疼了。
对于上面三个问题,换了一种表示方法:
//(首先,我是一个东西,这里叫对象。)
//我的年龄是多少?
My.Age=24
//我的体重是多少?
My.Weight=70
//我的上衣是什么颜色?
//(在自然界里,我是一个东西,我的上衣也是一个东西,所以这里就需要这样表示。)
My.Jacket.Color=黑色
好了,扯蛋完了,回归正题。
站在“引用”这个东西的角度来看,它里头的值是什么,无所谓啦!
引用只是用来指向一个东西,至于怎么处理这个东西,就看引用的类型了,是 int (值类型),就当它他是一个整数,是 object(引用类型),就知道它是一个内存地址,就去这个内存地址里去取相应类型的 object。
很多人执迷于引用类型设计的神秘性,又被这种神秘性所迷惑。比如 C# 里为什么 string 类型的变量能当对象来用,却能像值类型那样简单的使用(赋值等)。
弄清这个问题不难,但是要先解一下前面我对面向对象这个思想的简单演示(上面使用变量记录我的年龄、体重及上衣颜色等信息的那个例子)。
面向对象最重要的几个特性大家应该都耳熟能详,经常被提的就是“封装、继承、多态……”其中当然最为出色的,也最为常用的一个特性就是“封装”。封装就是将具有相关性的一组数据作为一个整体来进行传递(或访问),有点像数组或Hashtable,但是要比这两个使用起来更加方便,也更人性化一点。
对象里保存一些值,使用的是“属性”,当然,属性也可以是对象。这样就有一个非常好的好处——还是人性化。
比如我妈妈的弟弟的爸爸的老婆是我姥姥,用面向对象的思想进行表示:
My.Mother.Brother.Father.Wife == My.Grandma
OK,看到面向对象的好处了吧!他能把世间万物的关联,非常形象的联系在一起,非常直观的表示出来……庆贺一下……
(又扯蛋远了……)
一个对象,可能很大,可能会有很多的属性,存很多的值。这样一来,肯定就不可能放到一个内存地址上,而需要放在一批内存单元里。一批内存地址,用一个引用来指向,所以,这里要求内存将一个对象保存在一批连续的地址上,然后用这个引用指向这批内存地址的头部(学过C的人应该很熟悉吧,这应该就是C里的指针)。
这就是引用类型和值类型的实质差别。
好了,下面讨论一下运算符等号(赋值符号)的用处。
大部分计算机语言里,赋值符号用的都是等号=。等号可以将一个数据赋给一个变量(引用),不管这个数据是一个独立的值,还是一个对象。比如 a=3 或 Father=new People(“张三”),这样两个语句就表示让 a 这个变量的值等于数字 3,让 Father 这个变量等于名叫“张三”的这个人。
下面,看一段代码:
int B=4;
int A=B;
B=5;
这两条语句执行过以后,变量A的值等于4,这没有任何疑问。Over,再看一段代码:
string s1 = "123";
string s2 = s1;
s1 = "123456";
这样,s2等于"123",很正常啊,会有什么疑问呢?可能有人说:“这是对象啊!引用类型的对象啊!”可又有什么差别呢?
这里我来引用面向对象的思想举一个简单的例子:
比如我找了个女朋友,叫“123”,也就是说,我,这个对象,的女朋友,属性,等于名叫“123”的这个人。OK
后来,出现了个孙子,追上了我女朋友。这时候,我还没有和女朋友分手,这个时候,叫123的这个女人,既是我女朋友,又是内孙子的女朋友。OK(表示哀悼)
后来,我又找了个美女,叫123456。
这时候,我女朋友叫123456,内孙子的女朋友还是123。(它要是敢也是123456,这个世界就乱了,CAO)
OVER,使用代码表示一下:
My.GirlFriend=new Person(“123”);
SunZi.GirlFriend=My.GirlFriend;
My.GirlFriend=new Person(“123456”);
这个例子,很清楚了吧。
再举一个例子,来从另一个角度展示一下引用类型的实质。
比如,我爸以前用的是一个我哥(亲哥哥)给他的Nokia手机,后来我看太旧了,就买了一个新的HTC。我哥后来手机没电了,要用我爸的手机打电话,拿回来的不再是那个破Nokia了,而是我给买的HTC。
用程序表示,代码如下:
P=new Person();
My.Brother.Father=P;
My.Father=P;
My.Brother.Father.Mobile=”Nokia”;
My.Father.Mobile=”HTC”;
mobile=My.Brother.Father.Mobile; //mobile=”HTC”
完了,看懂了吧。不再解释。
OK,All Over。
其它的不讲了,这就是我个人对值类型和引用类型的理解。不知道是不是绝对合理,但是我觉得要是我,我就这么设计。不讲深层的什么蛋疼技术,希望对看到的人有所帮助。。