天天看點

靜态成員在PHP中是怎麼繼承的?

靜态成員在PHP中是怎麼繼承的?

靜态成員,也就是用static修飾的變量或者方法,如果搞不清楚它們實作的原理,就很容易會出現一些錯誤。這次我們來研究的是在繼承中靜态成員的調用情況。首先來看這樣一段代碼:

class A
{
    static $a = 'This is A!';

    public function show()
    {
        echo self::$a, PHP_EOL;
        echo static::$a, PHP_EOL;
    }
}

class B extends A
{
    static $a = 'This is B!';

}

$b = new B;
$b->show();      

之前的文章中,我們有說過self的問題。self僅僅隻是指向目前這個類。注意,是類,不是執行個體化後的對象。是以上面的輸出結果是:

This is A!
This is B!      

好了,有了這個基礎之後,我們知道靜态成員是和類有關的,和對象無關。那麼以下的代碼也就更容易了解了。

class C
{
    static $c = 1;
    public $d = 1;
}
class D extends C
{
    public function add()
    {
        self::$c++;
        $this->d++;
    }
}

$d1 = new D();
$d2 = new D();

$d1->add();
echo 'c:' . D::$c . ',d:' . $d1->d . ';', PHP_EOL;

$d2->add();
echo 'c:' . D::$c . ',d:' . $d2->d . ';', PHP_EOL;      

直接讀代碼能推導出輸出的結果嗎?其實隻要掌握了上文中所說的原則,這段代碼就很容易了解了。$c是靜态變量,$d是普通變量。通過類執行個體的add()方法進行操作後,$c因為是和類有關,是以不管是哪個執行個體對象,操作它之後都會是共享的。而$d作為普通變量,它的作用域僅限制在目前這個執行個體對象中。是以,輸出的結果是:

c:2,d:2;
c:3,d:2;      

最後,我們還是來複習一次self、parent和static關鍵字。

class E {
    public static function test(){
        echo "This is E test!";
    }
}

class F extends E{
    public static function t(){
        self::test();
        parent::test();
        static::test();
    }

    public static function test(){
        echo "This is F test!";
    }
}

F::t();