Расширение класса в PHP - PullRequest
       12

Расширение класса в PHP

2 голосов
/ 14 сентября 2011
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 не выполняет свою функцию?

Ответы [ 5 ]

4 голосов
/ 14 сентября 2011

Посмотрите на код в getInstance:

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

Все эти self указывают на A, а не на класс, который был вызван. В PHP 5.3 вводится то, что называется «поздняя статическая привязка» , что позволяет указывать на вызываемый класс, а не на класс, где существует код. Вам нужно использовать ключевое слово 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 голосов
/ 14 сентября 2011

Поскольку вы использовали self в getInstance класса A, когда вы вызываете getInstance в классе B, я полагаю, что self все еще ссылается на класс A ... если это имеет смысл.

Таким образом, вы вызываете doStuff () для двух экземпляров A.

2 голосов
/ 14 сентября 2011

Попробуйте следующий код для getInstance ()

public static function getInstance(){

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

    return self::$instance;
  }
2 голосов
/ 14 сентября 2011

Это потому, что PHP (в используемой версии) связывает статические функции с классом, в котором они были определены.

Итак, B::getInstance() возвращает объект класса А.

Я считаю, что это было изменено в PHP 5.3+, так как это было источником большой боли для многих (включая меня!).

Некоторые подробности по этому адресу: http://php.net/manual/en/language.oop5.late-static-bindings.php

1 голос
/ 14 сентября 2011

self :: все еще в классе A, независимо от того, как вы его называете

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...