Разве конструкторы абстрактных классов не вызывается неявно, когда создается экземпляр производного класса? - PullRequest
59 голосов
/ 23 февраля 2010

Возьмите этот пример:

abstract class Base {
    function __construct() {
        echo 'Base __construct<br/>';
    }
}

class Child extends Base {
    function __construct() {
        echo 'Child __construct<br/>';
    }
}

$c = new Child();   

Исходя из фона C #, я ожидаю, что результат будет

База __construct
Дочерняя __construct

Тем не менее, фактический результат составляет всего

Child __construct

Ответы [ 3 ]

102 голосов
/ 23 февраля 2010

Нет, конструктор родительского класса не вызывается, если дочерний класс определяет конструктор.

Из конструктора вашего дочернего класса вы должны вызвать конструктор родительского класса:

parent::__construct();

Передача параметров, если необходимо.

Как правило, вы будете делать это в начале конструктора дочернего класса, перед любым конкретным кодом; это означает, что в вашем случае у вас будет:

class Child extends Base {
    function __construct() {
        parent::__construct();
        echo 'Child __construct<br/>';
    }
}


И, для справки, вы можете взглянуть на эту страницу руководства по PHP: Конструкторы и деструкторы - здесь говорится (цитирование) :

Примечание: Родительские конструкторы не вызываются неявно, если дочерний класс определяет конструктор.
Для того, чтобы запустить родительский конструктор, вызов parent::__construct() в пределах требуется дочерний конструктор.

6 голосов
/ 23 февраля 2010

Я только что нашел это в документах :

Примечание: родительские конструкторы не являются вызывается неявно, если дочерний класс определяет конструктор. Для того, чтобы бежать родительский конструктор, вызов parent :: __ construct () внутри дочернего элемента требуется конструктор.

3 голосов
/ 08 марта 2017

Если вам нужно то же поведение, что и в C #, то есть родительский конструктор всегда выполняется перед дочерним конструктором, вы можете создать фиктивный класс конструктора для ваших дочерних классов и объявить его как абстрактную функцию в вашем абстрактном родительском классе.

* 1003 Е.Г. *

abstract class Test{
  abstract public function __childconstruct();
  public function __construct(){
    echo "SOME CODE".PHP_EOL;
    $this->__childconstruct();
  }
}

class TestExtended extends Test{
  public function __childconstruct(){
    echo "SOME OTHER CODE FROM EXTENDED CLASS".PHP_EOL;
  }
}

$a = new TestExtended();

/* SOME CODE
   SOME OTHER CODE FROM EXTENDED CLASS */
...