2011-09-14 44 views
2
class A{ 
    private static $instance; 

    public static function getInstance(){ 

    if(!(self::$instance instanceof self)) 
     self::$instance = new self(); 

    return self::$instance; 
    } 

    public function doStuff(){ 
    echo 'stuff'; 
    } 


} 

class B extends A{ 
    public function doStuff(){ 
    echo 'other stuff'; 
    } 
} 

A::getInstance()->doStuff(); // prints "stuff" 

B::getInstance()->doStuff(); // prints "stuff" instead of 'other stuff'; 

我在做什麼錯?在PHP中擴展一個類

爲什麼B類不運行它的功能?

回答

4

看在getInstance代碼調用它:

if(!(self::$instance instanceof self)) 
     self::$instance = new self(); 

所有這些self的立場給A,而不是被調用的類。 PHP 5.3引入了一種叫做"late static binding"的東西,它允許你指向被調用的類,而不是指向代碼所在的類。您需要使用static關鍵字:

class A{ 
    protected static $instance; // converted to protected so B can inherit 

    public static function getInstance(){ 
    if(!(static::$instance instanceof static)) 
     static::$instance = new static(); // use B::$instance to store an instance of B 

    return static::$instance; 
    } 

    public function doStuff(){ 
    echo 'stuff'; 
    } 
} 

不幸的是,這將失敗,如果你不具備PHP 5.3最少。

4

因爲您在類A的getInstance中使用self,所以當您在類B中調用getInstance時,我相信self仍然引用類A ...如果這是有道理的。

因此,基本上,你在A的兩個實例調用doStuff()

1

自我::仍處於A級,不管你用

2

這是因爲PHP(在您正在使用的版本)的靜態綁定功能,它們被定義的類。

所以B::getInstance()返回A類的一個對象

我相信這已經在PHP 5.3+中改變了,因爲它對很多人來說都是一個巨大的痛苦(包括我自己在內)!

這方面的一些細節是安裝在: http://php.net/manual/en/language.oop5.late-static-bindings.php

2

試用的getInstance)下面的代碼(

public static function getInstance(){ 

    if(!self::$instance) 
    { 
     $curClass = get_called_class(); 
     self::$instance = new $curClass(); 
    } 

    return self::$instance; 
    }