【PHP】關於靜態方法 與 self、static、parent

function載入後會取得記憶體位置,

透過static宣告,在後續載入時,記憶體位置都一樣,相對較節省記憶體。

但也因為共享記憶體,所以要特別注意存取權限以及存取時機。

self、static、parent (資料來源)

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();

輸出結果

A
C
C

說明

1、
A::foo();
可以在任何地方執行的,固定指向A的foo();

2、
parent::foo();
C的parent是B,B的parent是A,回溯找到了A的foo方法;
static::who();
static::調用的方法會被子類覆蓋,所以優先調用C的who()方法,
如果C的who方法不存在會調用B的who方法,
如果B的who方法不存在會調用A的who方法。
所以,輸出結果是’C’。

3、
self::foo();
這個self::是在B中使用的,所以self::等價於B::,
但是B沒有實現foo方法,B又繼承自A,
所以我們實際上調用了A::foo()這個方法。
foo方法使用了static::who()語句,導致我們又調用了C的who函數。

 

class Father {
    public function getNewFather() {
        return new self();
    }

    public function getNewCaller() {
        return new static();
    }
}

class Sun1 extends Father {
}

class Sun2 extends Father {
}

$f = new Father();
$sun1 = new Sun1();
$sun2 = new Sun2();

echo get_class($f->getNewFather())."";
echo get_class($f->getNewCaller())."";
echo get_class($sun1->getNewFather())."";
echo get_class($sun1->getNewCaller())."";
echo get_class($sun2->getNewFather())."";
echo get_class($sun2->getNewCaller())."";

輸出結果

Father
Father
Father
Sun1
Father
Sun2

說明

self本身,無論在什麼地方調用,都是取到Father本身。
static,只有在出現繼承的時候才會有區別。就是返回真正的調用者。