鍍金池/ 問答/PHP/ PHP關(guān)于靜態(tài)綁定的一點(diǎn)疑問

PHP關(guān)于靜態(tài)綁定的一點(diǎn)疑問

class A {
    public static function foo() {
        static::who();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();

輸出結(jié)果為ACC.我的疑問是為什么第二個(gè)是C而不是B?還請(qǐng)各位大神賜教

回答
編輯回答
尛曖昧

如果靜態(tài)調(diào)用使用parent::或者 self::將轉(zhuǎn)發(fā)調(diào)用信息,也就是運(yùn)行時(shí)的調(diào)用者C

2017年1月2日 21:40
編輯回答
傲嬌范

自己來回答一下。靜態(tài)調(diào)用分為轉(zhuǎn)發(fā)調(diào)用和非轉(zhuǎn)發(fā)調(diào)用。
轉(zhuǎn)發(fā)調(diào)用:進(jìn)行靜態(tài)調(diào)用時(shí)使用static::,self::,parent::,forword_static_call進(jìn)行調(diào)用。換句話說就是沒有指定類名的靜態(tài)條用。
非轉(zhuǎn)發(fā)調(diào)用:進(jìn)行靜態(tài)調(diào)用時(shí)使用類名::或者進(jìn)行非靜態(tài)調(diào)用時(shí)使用類名->方法名調(diào)用。換句話說就是明確地指定類名的靜態(tài)調(diào)用和非靜態(tài)調(diào)用。

再說的通俗一點(diǎn),顧名思義,非轉(zhuǎn)發(fā)調(diào)用前面有類名所以調(diào)用的函數(shù)一定是屬于“這個(gè)類的”,不需要轉(zhuǎn)到別的類。轉(zhuǎn)發(fā)調(diào)用就是由于前期的靜態(tài)綁定導(dǎo)致在后面調(diào)用靜態(tài)方法時(shí)可能“轉(zhuǎn)發(fā)到其他的類”。

在PHP的官方文檔里,對(duì)于后期靜態(tài)綁定是這樣說的:后期靜態(tài)綁定工作原理是存儲(chǔ)了在上一個(gè)“非轉(zhuǎn)發(fā)調(diào)用”(non-forwarding call)中的類名。意思是當(dāng)我們調(diào)用一個(gè)轉(zhuǎn)發(fā)調(diào)用的靜態(tài)調(diào)用時(shí),實(shí)際調(diào)用的類是上一個(gè)非轉(zhuǎn)發(fā)調(diào)用的類。
現(xiàn)在我一步步分析上面的例子
1.C::test().毫無疑問,這是一個(gè)非轉(zhuǎn)發(fā)調(diào)用,因?yàn)?:前面有類名C。
2.進(jìn)入test()方法,有三個(gè)靜態(tài)調(diào)用A::foo(),parent::foo(),self::foo(),對(duì)于這三個(gè)靜態(tài)調(diào)用來說,他們的非轉(zhuǎn)發(fā)調(diào)用類就是C。
3.現(xiàn)在執(zhí)行A::foo(),這是一個(gè)非轉(zhuǎn)發(fā)調(diào)用。A::foo()中的代碼是static::who,這是一個(gè)轉(zhuǎn)發(fā)調(diào)用,對(duì)于這個(gè)轉(zhuǎn)發(fā)調(diào)用來說他的非轉(zhuǎn)發(fā)調(diào)用類就是不再是C而是A(因?yàn)橹皥?zhí)行了A::foo())。因此執(zhí)行的結(jié)果為A
4.現(xiàn)在執(zhí)行parent::foo(),這是一個(gè)轉(zhuǎn)發(fā)調(diào)用,轉(zhuǎn)發(fā)到哪里呢?就是它的上一個(gè)非轉(zhuǎn)發(fā)調(diào)用的類,也就是類C(在步驟2中提到的)。在這里一定要注意雖然在這之前執(zhí)行了A::foo(),但是parent::foo()的上一個(gè)非轉(zhuǎn)發(fā)調(diào)用的類任然是類C。因此執(zhí)行的結(jié)果是C.
5.現(xiàn)在執(zhí)行self::foo(),這個(gè)和parent::foo()一樣都是轉(zhuǎn)發(fā)調(diào)用,因此也輸出C。

2018年9月1日 11:25
編輯回答
囍槑

這就是靜態(tài)調(diào)用static的意義啊.
你用parent或者self會(huì)顯示 當(dāng)前調(diào)用者 , 也就是C .
所以,才出現(xiàn)了static

2018年2月14日 04:06