【问题标题】:Extending a class in PHP在 PHP 中扩展一个类
【发布时间】:2011-11-17 04:00:50
【问题描述】:
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';

我做错了什么?

为什么B类不运行它的功能?

【问题讨论】:

    标签: php class extend


    【解决方案1】:

    getInstance中的代码:

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

    所有selfs 都指向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,这将失败。

    【讨论】:

      【解决方案2】:

      因为您在 A 类的 getInstance 中使用了 self,所以当您在 B 类中调用 getInstance 时,我相信 self 仍然是指 A 类...如果这有意义的话。

      所以基本上,你在 A 的 2 个实例上调用 doStuff()。

      【讨论】:

        【解决方案3】:

        这是因为 PHP(在您使用的版本中)将静态函数绑定到定义它们的类。

        所以B::getInstance() 返回一个 A 类的对象。

        我相信这在 PHP 5.3+ 中已经改变了,因为它给许多人(包括我自己!)带来了极大的痛苦。

        关于这方面的一些细节在: http://php.net/manual/en/language.oop5.late-static-bindings.php

        【讨论】:

          【解决方案4】:

          试试下面的getInstance()代码

          public static function getInstance(){
          
              if(!self::$instance)
              {
                $curClass = get_called_class();
                self::$instance = new $curClass();
              }
          
              return self::$instance;
            }
          

          【讨论】:

            【解决方案5】:

            self:: 仍然属于 A 类,不管你怎么称呼它

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-11-03
              • 1970-01-01
              • 2013-06-14
              • 1970-01-01
              • 2016-04-09
              • 1970-01-01
              相关资源
              最近更新 更多