引言
之前的文章我們已經講過,在 php 類的創建過程中,使用 self 作為類本身的引用,使用 $this 作為類對象的引用。
而在 self 和 static 的使用上,有著細微的差別。特別是類繼承過程中,self 可能帶來意想不到的反應,也正如那篇文章所說,建議使用 static 作為類本身的引用。
本文再來探討,類內的 new self 與 new static 有什么區別。
學習時間
self 總是指向 new 關鍵字所聲明的類;static 在靜態綁定中,可以指向層級結構中的任意類。
下面舉一個例子。
類B繼承了類A的方法。對于 get_self 方法,返回的是類A本身。而static則返回的是調用者的類,也就是說,誰調用,static就指向誰。self 則持續地指向聲明的類。
上面的代碼,我們在類 A 中使用的是 static 靜態方法,如果是動態方法,則需要使用到函數 get_class 用于獲取類名。下面是一個示例:
方法 create2 中使用了 return new static(),毫無疑問,調用該方法的是對象 $b,那么返回的也肯定是 class B 本身。
方法 create1 中使用 get_class($this) 通過對象本身 $this,獲取類名。因為 $this 指向 class B,所以返回的是 B,而 return new $class() 等同于 return new B(),也就是類B本身。
再進一步
既然我們區分了 self 可以不經類實例化就可以使用其方法,static 必然是實例化后對象的引用,那么看下面這個例子,就會很清楚了:
class Foo {
public $name = static::class;
}
$Foo = new Foo;
echo $Foo->name; // Fatal error
上面的代碼會出錯。Fatal error 發生位置不是在 $Foo->name 行,而是聲明行。因為 static::class 會發生錯誤。在對屬性賦值時,只能使用非靜態綁定的對象,同理 $this 的方法可肯定不行。要使用 self。
class Foo {
public $name = self::class;
}
$Foo = new Foo;
echo $Foo->name; // Foo
這樣寫就沒錯了。因為 self 引用的是類本身,調用 class 靜態方法也完全行得通。
寫在最后
在程序架構時這些基類的設計很關鍵,需要詳細規劃和細分業務關系,self static $this 這些高頻關鍵字,需要我們熟練掌握。
HAppy coding :_)