1. 程式人生 > >PHP中的後期靜態綁定

PHP中的後期靜態綁定

all 方法 post 存儲 cal static 修飾 public self

<?php
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();
        A::foo();
        B::foo();*/
        A::foo();
        parent
::foo(); self::foo(); } public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } // 當有parent和self前綴時,可以考慮換成具體的類名進行思考 // 如果函數的內容是static前綴,則要考慮最後一次“非轉發調用”的類名 // 當有parent和self前綴時,如此例,只需要考慮調用這個函數的類就可以了,在這裏是C::test() class
C extends B { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } C::test(); // A C C
  • 轉發調用: 進行靜態調用時前面有static修飾的
  • 非轉發調用: 直接通過類名,方法名調用的
  • 後期靜態綁定工作原理是存儲了在上一個“非轉發調用”(non-forwarding call)中的類名
  • 意思是當我們調用一個轉發調用的靜態調用時,實際調用的類是上一個非轉發調用的類。
  • 分析一下上面的例子
  • Class C的test方法中的三個方法,它們的非轉發調用類都是C,因為它是直接通過C::test()方式訪問的
    • A::foo() 非轉發調用 方法內部又進行了轉發調用,這時的上一個非轉發調用的類是A,所以輸出A
    • parent::foo() 調用了Class B的foo方法,該方法內進行了一次轉發調用,這時的上一個非轉發調用的類是C,所以輸出C
    • self::foo() 調用了自身的foo方法,該方法內也進行了一次轉發調用,道理同上,所以輸出C
      • 可以嘗試將Class C foo方法中的static::who()分別替換成self::who(), parent:who() 看看效果,前者輸出C 後者輸出B

PHP中的後期靜態綁定