PHP中的static關于靜態(tài)變量和方法的問題也是面試中經(jīng)常會出現(xiàn)的問題,這種問題多看手冊搞明白原委就能解決,只是確實關于靜態(tài)變量的問題還是比較繞的,這里我們就結合手冊用實際的代碼來看!
先準備一個類,這里面有靜態(tài)變量、靜態(tài)方法,其中showV()方法是靜態(tài)方法調(diào)用靜態(tài)變量,showVV()方法是普通方法調(diào)用靜態(tài)變量,showVVV()方法是普通方法調(diào)用靜態(tài)方法。 從注釋中可以看出第一個問題,普通方法使用$this調(diào)用靜態(tài)方法會報錯,也就是說,$this這個東東對于一切靜態(tài)的東西都是不友好的,不信您打開注釋試試,也可以去調(diào)用靜態(tài)的$v變量,直接就是語法錯誤的提示。 接下來,我們實例化類,并開始一些測試 $t = new Test();
那么問題來了,靜態(tài)方法中不能使用$this,如何獲得變量內(nèi)容呢?請參考單例模式,將來我們會在設計模式的系列文章中講到,這里先賣個關子,大家也可以自己研究下。 上面是正常來說一些比較簡單的靜態(tài)屬性和方法的演示,接下來好玩的東西就來了。
class Calculate 看著代碼很多,其實都是在講一件事兒,如果是普通的$a和$b,那么每次都在重新賦值,echo出來的都是0,但是靜態(tài)屬性可不一樣。靜態(tài)屬性是運行時計算的,只在第一次賦值的時候是真正的賦值操作,而后并不會進行賦值,可以相當于這一行代碼不存在。 **靜態(tài)變量只在局部的作用域中存在,離開這個作用域也不會丟失,當然也不能再次初始化。**學過前端的同學一定會拍案而起,這不是閉包的作用域嘛??確實很像,而且用處也非常像,比如我們做一個遞歸: function test1() 在不了解static之前,結束遞歸我們可能需要給方法傳遞一個數(shù)字進來,但現(xiàn)在似乎是不需要了,使用內(nèi)部的靜態(tài)變量就可以解決了。
又是一大串代碼,啥也不說,先復制下來運行一下看看結果是不是一樣。在使用引用對象時,我們賦值的是內(nèi)存引用地址。但是同樣的原因,靜態(tài)屬性是運行時產(chǎn)生的,而引用地址不是靜態(tài)地存儲,于是,賦不上值了唄,永遠會是NULL。不信你接著用getRefObj()再生成幾個試試。實際應用中反正要記住,這種情況下千萬不要把引用值賦給靜態(tài)變量就行了,而上面原因的理解確實還是比較繞的,能講明白最好,講不明白就記住這個事兒。
先看這一段,使用self輸出的結果會是A,但如果使用普通的類實例化,并且使用普通方法的話,輸出的會是B,大家可以嘗試下。原因呢,就是self是取決于當前定義方法所在的類。這就是靜態(tài)屬性方法的另一大特點,不實例化,跟隨著類而不是實例。 class A{...},這個東西叫做類,是對現(xiàn)實的抽象,我們可以理解為一個模板,這里面的東西是假的,沒有生命的。$a = new A了之后,這個$a才是對象,相當于是復制一了個模板做了一個真的東西出來,是有生命的。就好像我們做一個錘子,需要一個模具,這玩意就是類,然后澆鑄金屬后成型拿出來,這玩意就是對象。一個對象有真正的內(nèi)存地址空間的。 非靜態(tài)的屬性和方法是在對象中的,是我們澆進去的金屬。也就是new了之后才有的東西,而靜態(tài)屬性和方法是依附于class A的,是運行時進行編譯讀取的。 現(xiàn)在我們回過頭來看最早的例子,普通方法中調(diào)用靜態(tài)方法或變量,實際上就是在這個實例化對象中調(diào)用了Test::showV(),只是我們使用了self關鍵字而已。依然是走的靜態(tài)過程而不是這個對象中真的包含了showV()這個方法,因此,$this當然取不到啦! 那么,如何讓父類A中test()方法去調(diào)用到子類的who()方法呢?
沒錯,使用static::關鍵字這種形式調(diào)用,static表示運行最初時的類,不是方法定義時的類。這樣就完成了后期靜態(tài)綁定。另外,parent::和self::是會轉發(fā)這個鏈條的。
這個例子看著很繞,但其實結論就一個,如果父類使用了static關鍵字來調(diào)用父子類都有的內(nèi)容,那么就是以哪個子類在外面進行調(diào)用了為準,就像普通類的方法調(diào)用 一樣。反過來,self就是以這個self關鍵字所在的類為準。 說了這么多,也算是把static靜態(tài)的特性講解的差不多了。在實際應用中還是要綜合考慮,不能因為靜態(tài)屬性方便就全都使用靜態(tài)屬性和方法或者完全不使用,還是要結合各路業(yè)務需求進行取舍。 具體代碼: https://github.com/zhangyue0503/php/blob/master/newblog/php-static.php |
|
來自: 硬核項目經(jīng)理 > 《待分類》