2011-09-14 45 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; 
    }