什么叫后期靜態系結呢?其實我們在之前的文章PHP中的static中已經說過這個東西了,今天我們還是再次深入的理解一下這個概念,
首先,我們通過一段代碼來引入后期靜態系結這一概念:
class A
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
public static function test()
{
self::who();
}
}
class B extends A
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
}
B::test(); // A
在這段代碼中,我們使用了self關鍵字,當使用B類呼叫test()靜態方法時,self指向的是A類的who()方法,因此,輸出的是A,別激動,這是普通的靜態系結,self關鍵字呼叫的內容取決于它定義時所在的類,也就是說不管怎么繼承,用哪個子類來呼叫test()方法,self關鍵字都會呼叫的是A類的who()方法,
而后期靜態系結呢?其實就有點像實體化的類物件,每個實體化的物件,呼叫的都是自身,而不是父類的屬性方法,普通的靜態呼叫可不是這樣,但是現實中我們又有這樣的需求,就像實體化物件的呼叫方式一樣來呼叫靜態屬性方法,這時,我們就可以使用static關鍵字來實作后期靜態系結,
class C
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
public static function test()
{
static::who();
}
}
class D extends C
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
}
D::test(); // D
當使用static關鍵字后,這里D類呼叫的test()方法內部呼叫的who()就是D類自己了,
官方檔案中的定義如下:
當進行靜態方法呼叫時,該類名即為明確指定的那個(通常在 :: 運算子左側部分);當進行非靜態方法呼叫時,即為該物件所屬的類,
該功能從語言內部角度考慮被命名為“后期靜態系結”,“后期系結”的意思是說,static:: 不再被決議為定義當前方法所在的類,而是在實際運行時計算的,也可以稱之為“靜態系結”,因為它可以用于(但不限于)靜態方法的呼叫,
除了self和static關鍵字外,我們還有一個parent關鍵字,這個關鍵字的意義就很明顯了,呼叫父類的靜態內容,我們同時用三個關鍵字一起來進行測驗:
class E
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
public static function test()
{
self::who();
static::who();
}
}
class F extends E
{
public static function who()
{
echo __CLASS__, PHP_EOL;
}
}
class G extends F
{
public static function who()
{
parent::who();
echo __CLASS__, PHP_EOL;
}
}
G::test();
// E
// F
// G
最后,我們再來看兩個PHP的方法,一個是get_called_class()方法,用來獲取當前呼叫的是哪個類,在靜態方法中可以根據呼叫方式判斷當前類是哪個類來進行其他的業務邏輯操作,另一個是forward_static_call()方法,用于靜態方法的呼叫,
class H
{
public static function who()
{
echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
}
public static function test()
{
echo get_called_class(), PHP_EOL;
forward_static_call('who', 'a', 'b'); // xxx:a,b
forward_static_call(['I', 'who'], 'c', 'd'); // I:c,d
forward_static_call_array(['H', 'who'], ['e', 'f']); // H:e,f
}
}
class I extends H
{
public static function who()
{
echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
}
}
function who()
{
echo 'xxx:' . join(',', func_get_args()), PHP_EOL;
}
H::test(); // H
// xxx:a,b
// I:c,d
// H:e,f
I::test(); // I
// xxx:a,b
// I:c,d
// H:e,f
注意,如果forward_static_call()不指定類名的話,將呼叫全域的方法,forward_static_call_array()則是將引數使用陣列進行傳遞,
測驗代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/%E5%90%8E%E6%9C%9F%E9%9D%99%E6%80%81%E7%BB%91%E5%AE%9A%E5%9C%A8PHP%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8.php
參考檔案:
https://www.php.net/manual/zh/language.oop5.late-static-bindings.php
https://www.php.net/manual/zh/function.get-called-class.php
https://www.php.net/manual/zh/function.forward-static-call.php
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/264066.html
標籤:PHP
上一篇:設計模式之單一職責原則
