初接觸程式設計,確實感覺它抽象,而且很多時候覺得抽象的讓人蛋疼。
以變數為例,最初還只是簡單的數值,這很容易讓人理解。可自物件導向思想流行以後,變數又引入了引用型別。突然之間,許多人又開始蛋疼起來。
其實,對變數而言,變數只是變數,引用型別的變數只是在使用變數訪問數值的時候進行了一些稍複雜一點的處理——從以前的直接取值到從其值所表示的記憶體位址找相應的物件取值。
打個比方,將我作為乙個主體。
//我的年齡是多少?
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。
其它的不講了,這就是我個人對值型別和引用型別的理解。不知道是不是絕對合理,但是我覺得要是我,我就這麼設計。不講深層的什麼蛋疼技術,希望對看到的人有所幫助。。
引用型別和值型別
c 是一種型別安全的語言。每乙個變數都要求定義為乙個特定的型別,並且要求儲存在變數中的值只能是這種型別的值。變數既能儲存值型別,也可以儲存引用型別,還可以是指標。這一課將講述前兩種型別,關於指標的討論我們將在下一課中進行。下面是關於值型別和引用型別不同點的概論 如果乙個變數v儲存的是值型別,則它直接...
引用型別和值型別
c 中值型別和引用型別作為方法引數傳遞的時候其實都可以說是 值 的傳遞,只不過這裡的 值 指代的東西有所區別。當方法的引數為值型別時,方法傳遞的是值本身的值。當方法的引數為引用型別時,方法傳遞的則是應用型別的引用的位址,也就是引用型別位址在棧上的值。舉個引用型別作為引數傳遞的例子 static vo...
值型別和引用型別
為了更好地說明兩種型別之間的區別,借用如下的 來說明 值型別引用型別 記憶體分配地點 分配在棧中 分配在堆中 效率效率高,不需要位址轉換 效率低,需要進行位址轉換 記憶體 使用完後,立即 使用完後,不是立即 等待gc 賦值操作 進行複製,建立乙個同值新物件 只是對原有物件的引用 函式引數與返回值 是...