程序最終都將在內存中執行,變量只有分配到內存時才能被訪問
靜態方法是以類爲做用域的方法,在類加載的時候就會分配內存。
普通變量屬於類的對象,只有在類的對象產生(建立類的實例)時纔會分配內存
靜態方法中訪問非靜態的方法或屬性會報錯,是由於非靜態方法還沒分配到內存
訪問內存中不存在的變量是出錯的。
複製代碼
在面向對象的編程中,咱們通常是把類當成對象的模板,把對象當成活動的組件來進行操做編程
面向對象編程中,咱們大多數的操做都是經過類的實例(即對象,而不是類的自己)來完成的 。
經過對象來調用方法或者屬性,必須先實例化一個對象出來this
$obj = new ExampleClass(); //實例化對象,此時分配到內存
$obj -> doSomething(); //對象的操做通常用箭頭來實現
複製代碼
固然,咱們不只能夠經過對象來訪問類的方法和屬性,還能夠經過類而不是對象來直接訪問屬性和方法,被訪問的方法和屬性必須是靜態的(static)spa
class ExampleClass {
static public $test;
static public function doSomething()
{
...
}
...
}
#加載ExampleClass類的時候,就給靜態方法和屬性分配了內存
ExampleClass::doSomething(); //直接訪問類靜態方法用雙冒號::
ExampleClass::$test;
#靜態方法也能夠經過實例化對象來調用(此時不會再給靜態變量分配新的內存)
$obj = new ExampleClass();
$obj -> doSomething();
複製代碼
在方法內部直接調用靜態方法和非靜態方法時要注意,靜態方法是不能直接調用非靜態方法或屬性的,而同靜態的方法和屬性是能夠隨時被調用的。3d
class ExampleClass {
public $test
static public $staticTest;
static public function doSomething()
{
//$this -> test; 靜態方法內不容許調用$this,由於還沒實例化,內存找不到它
echo self::$staticTest;
}
public function getSomething()
{
echo $this -> test; //非靜態方法實例化後才能用,因此能調用非靜態方法和屬性
echo self::$staticTest;
}
...
}
#無實例化狀況下,靜態方法和屬性能夠隨時調用,非靜態的不能調用
ExampleClass::doSomething();
ExampleClass::$staticTest;
//ExampleClass::getSomething(); //無內存,調用報錯
//ExampleClass::$test(); //無內存,調用報錯
#實例化狀況下,均可以調用
$obj = new ExampleClass();
$obj -> getSomething();
$obj :: getSomething(); //用雙冒號調用非靜態方法,若是方法內有$this會報錯,由於用雙冒號調用時,是以類爲做用域,沒法訪問非靜態變量
$obj -> doSomething();
$obj :: doSomething();
複製代碼
補個草圖(我的觀點,歡迎指教)code
歸根到底,self 和 $this 能不能調用是內存分配以及做用域的問題。我的觀點,歡迎指教cdn