標籤:c style class blog code java
靜態成員是一種類變數,可以把它看成時屬於整個類而不是屬於類的某個執行個體。與一般的執行個體變數不同的是,靜態成員只保留一個變數值,而這個變數值對所有的執行個體都是有效,也就是說,所有的執行個體共用這個成員。
$this只表示類的當前執行個體,而 self:: 表示的是類本身,在類之外的代碼中不能使用這個操作符,而且它不能識別自己在繼承樹階層中的位置。也就是說,在擴充類中使用self 範圍時,self 可以調用基類中聲明的方法,但它調用的總是已經在擴充類中重寫的方法。與$this不同的是,在使用靜態變數時,必須在範圍限定符後面加上$符號。
在擴充類中,在基類的方法被重寫的情況下,使用 parent 範圍調用定義在基類中的方法。靜態成員也可以只屬於父類。如果在子類和父類中同時聲明了某個成員,也可以使用parant::在子類中訪問父類中的變數。在這種情況下,父類的靜態成員和子類的靜態成員儲存的是不同的值。
可以在 :: 操作符的左邊寫上類的名稱來靜態地訪問某個成員,這樣避免建立類的執行個體。不僅省略掉執行個體化類的代碼,而且還會更高效,因為類的每個執行個體都會佔用一小部分的系統資源。
在使用 :: 操作符訪問成員變數時,需要再次注意對$符號的使用。因為PHP當前不支援動態靜態變數的使用,也就是說不支援可變的靜態變數。在使用$this->$var時,被訪問的成員是包含在$var中的變數的值。而不用$符號訪問某個變數實際上尋找的是類的某個常量,而常量是不能通過$this來訪問的。
PHP6中提出的static::範圍使我們不再需要使用self::和parent::。當希望指向最終的實現功能的類時,就可以使用static::,這個限定符會在代碼執行之前立即計算出繼承層次機構上最後那個類的成員。之一過程被稱為延遲綁定,它使我們可以在子類中重寫某個靜態變數,並且也可以從某個在父類中聲明的函數中反問這個最終成員。
有時,可能有必要建立供所有類執行個體共用的欄位和方法,這些欄位和方法與所有的類執行個體有關,但不能由任何特定對象調用。例如,假設要編寫一個類,跟蹤網頁訪問者的數量。你一定不希望每次執行個體化該類時都把訪問者數量重設為0 ,此時就可以將該欄位設定為static範圍:
<?php class visitors { private static $visitors = 0; function __construct() { self::$visitors++; } static function getVisitors() { return self::$visitors; } } /* Instantiate the visitors class. */ $visits = new visitors(); echo visitors::getVisitors()."<br />"; /* Instantiate another visitors class. */ $visits2 = new visitors(); echo visitors::getVisitors()."<br />";?>
程式運行結果:
1
2
因為$visitors欄位聲明為static,所以對其值的任何改變都會反映到所有執行個體化對象中。還要注意,靜態欄位和方法應使用self關鍵字和類名來引用,而不是通過this和箭頭操作符。這是因為使用“正常”方法引用靜態欄位是不可能的,會導致語法錯誤。
不能在類中使用$this來引用為static欄位。
靜態變數
靜態變數是只存在於函數範圍的變數,不過,在函數執行完成後,這種變數的值不會丟失,也就是說,在下一次調用這個函數時,變數仍然會記得原來的值。要將某個變數定義為靜態,只需要在變數前加上 static 關鍵字即可。
在類中,static關鍵字有兩種主要用法,一是用來定義靜態成員,一是用來定義靜態方法。在類的內部,可以使用範圍限定符 (::) 來訪問不同層次範圍的變數。
靜態方法
靜態方法和非靜態方法之間有一個重要的區別:在調用靜態方法時,不再需要擁有類的執行個體。
靜態方法和非靜態方法使用原則:一是如果某個方法中不包含$this變數,就應該時靜態方法;如果不需要類的執行個體,可能還應該使用靜態類,這樣可以免去執行個體化類的工作。另,在靜態方法中時不能使用$this變數的,因為靜態方法不屬於某個特定的執行個體。