我們上面說過面向對象程式的機關就是對象,但對象又是通過類的執行個體化出來的,既然我們類會聲明了,下一步就是執行個體化對象了。
當定義好類後,我們使用new關鍵字來生成一個對象。
$對象名稱 = new 類名稱();
$p1=new Person();
這條代碼就是通過類産生執行個體對象的過程,$p1就是我們執行個體出來的對象名稱, 同理,$p2, $p3也是我們執行個體出來的對象名稱,一個類可以執行個體出多個對象,每個對象都是獨立的,上面的代碼相當于執行個體出來3個人來, 每個人之間是沒有聯系的, 隻能說明他們都是人類, 每個人都有自己的姓名, 性别和年齡的屬性,每個人都有說話和走路的方法,隻要是類裡面展現出來的成員屬性和成員方法,執行個體化出來的對象裡面就包含了這些屬性和方法。
對像在PHP裡面和整型、浮點型一樣,也是一種資料類,都是存儲不同類型資料用的,在運作的時候都要加載到記憶體中去用, 那麼對象在記憶體裡面是怎麼展現的呢?
記憶體從羅輯上說大體上是分為4段, 棧空間段, 堆空間段,代碼段, 初使化靜态段,
①.棧空間段
棧的特點是空間小但被CPU通路的速度快,是使用者存放程式中臨時建立的變量。由于棧的後進先出特點,是以棧特别友善用來儲存和恢複調用現場。從這個意義上講,我們可以把堆棧看成一個臨時資料寄存、交換的記憶體區。用于存儲占用空間長度不變并且占用空間小的資料類型的記憶體段,例如整型1、100、10000等在記憶體中占用空間是等長的,占用空間都是32位的4個位元組。還有double、boolean等都可以存儲在棧空間段中。
②.堆空間段
堆是用于存放程序運作中被動态配置設定的記憶體段,它大小并不固定,可動态擴張或縮減。用于存儲資料長度可變或占用記憶體比較大的資料。例如,字元串、數組和對象就存儲在這段記憶體中。
③.資料段
資料段用來存放可執行檔案中初始化全局變量,換句話說就是存放程式靜态配置設定的變量。
④.代碼段
代碼段是用來存放可執行檔案的操作指令,也就是說它是可執行程式在記憶體中的鏡像。代碼段需要防止在運作時被非法修改,是以隻準許讀取操作,而不允許寫入(修改)操作。例如程式中的函數就存儲在這段記憶體中。
對象類型的資料就是一種占用空間比較大的資料類型,并且是占用的空間不定長的資料類型,是以對象建立完成以後被存放在對記憶體中,但對象的引用還是存放在棧裡面的。程式在運作時,占記憶體中的資料是可以直接存取的,而堆記憶體是不可以直接存取的記憶體,但可以通過對象的引用名稱通路對象中的成員。
程式裡面不同的聲明放在不同的記憶體段裡面,
棧空間段是存儲占用相同空間長度并且占用空間小的資料類型的地方,比如說整型1, 10, 100, 1000, 10000, 100000等等,在記憶體裡面占用空間是等長的,都是64位4個位元組。
那麼資料長度不定長,而且占有空間很大的資料類型的資料放在那記憶體的那個段裡面呢?這樣的資料是放在堆記憶體裡面的。
棧記憶體是可以直接存取的,而堆記憶體是不 可以直接存取的記憶體。
對于我們的對象來說就是一種大的資料類型而且是占用空間不定長的類型,是以說對象是放在堆裡面的,但對象名稱是放在棧裡面的,這樣通 過對象名稱就可以使用對象了。
對于這個條代碼, $p1是對象名稱在棧記憶體裡面,new Person()是真正的對象是在堆記憶體裡面的,具體的請看下圖:
從上圖可以看出$p1=new Person();等号右邊是真正的對象執行個體, 在堆記憶體裡面的實體,上圖一共有3次new Person(),是以會在堆裡面開辟3個空間,産生3個執行個體對象,每個對象之間都是互相獨立的,使用自己的空間,在PHP裡面,隻要有一個new這個關鍵字出現就會執行個體化出來一個對象,在堆裡面開辟一塊自己的空間。
每個在堆裡面的執行個體對象是存儲屬性的,比如說,現在堆裡面的執行個體對象裡面都存有姓名、性别和年齡。每個屬性又都有一個位址。
$p1=new Person();等号的左邊$p1是一個引用變量,通過指派運算符“=”把對象的首位址賦給“$p1“這個引用變量, 是以$p1是存儲對象首位址的變量,$p1放在棧記憶體裡邊,$p1相當于一個指針指向堆裡面的對象, 是以我們可以通過$p1這個引用變量來操作對象, 通常我們也稱對象引用為對象。
驗證:
通過測試結果來看,解釋是對的。
$p1 是對象的指針而不是對象本身, obj2和 obj1都指向同一塊記憶體,同一個對象。這一點和OOP語言是一樣
object(Person)[2]
public 'name' => string 'test2' (length=5)
object(Person)[2]
可見對象的ID号是一個
如果想得到一個對象的副本,用$obj2 =clone $obj1; 用了clone後會産生一個新對象,配置設定記憶體,獨立于原來的obj1
參見手冊此頁 http://www.php.net/manual/zh/language.oop5.cloning.php
$obj2 = $obj1;
$obj2 = &$obj1;
一樣的效果,一樣的解釋?
對于object來說,是一樣的。 對于普通的變量是不一樣的。
$a = 1;
$b = $a;
$c = &$a;
不一樣的