3 回答

TA貢獻1808條經驗 獲得超4個贊
自己來回答一下。靜態調用分為轉發調用和非轉發調用。
轉發調用:進行靜態調用時使用static::,self::,parent::,forword_static_call進行調用。換句話說就是沒有指定類名的靜態條用。
非轉發調用:進行靜態調用時使用類名::或者進行非靜態調用時使用類名->方法名調用。換句話說就是明確地指定類名的靜態調用和非靜態調用。
再說的通俗一點,顧名思義,非轉發調用前面有類名所以調用的函數一定是屬于“這個類的”,不需要轉到別的類。轉發調用就是由于前期的靜態綁定導致在后面調用靜態方法時可能“轉發到其他的類”。
在PHP的官方文檔里,對于后期靜態綁定是這樣說的:后期靜態綁定工作原理是存儲了在上一個“非轉發調用”(non-forwarding call)中的類名。意思是當我們調用一個轉發調用的靜態調用時,實際調用的類是上一個非轉發調用的類。
現在我一步步分析上面的例子
1.C::test().毫無疑問,這是一個非轉發調用,因為::前面有類名C。
2.進入test()方法,有三個靜態調用A::foo(),parent::foo(),self::foo(),對于這三個靜態調用來說,他們的非轉發調用類就是C。
3.現在執行A::foo(),這是一個非轉發調用。A::foo()中的代碼是static::who,這是一個轉發調用,對于這個轉發調用來說他的非轉發調用類就是不再是C而是A(因為之前執行了A::foo())。因此執行的結果為A
4.現在執行parent::foo(),這是一個轉發調用,轉發到哪里呢?就是它的上一個非轉發調用的類,也就是類C(在步驟2中提到的)。在這里一定要注意雖然在這之前執行了A::foo(),但是parent::foo()的上一個非轉發調用的類任然是類C。因此執行的結果是C.
5.現在執行self::foo(),這個和parent::foo()一樣都是轉發調用,因此也輸出C。
- 3 回答
- 0 關注
- 408 瀏覽
添加回答
舉報