Подтвердить что ты не робот

Являются ли конструкторы абстрактного класса неявным образом вызваны при создании экземпляра производного класса?

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

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

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

$c = new Child();   

Исходя из фона С#, я ожидаю, что вывод будет

База __construct
Ребенок __construct

Однако фактический вывод - это просто

Ребенок __construct

4b9b3361

Ответ 1

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

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

parent::__construct();

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

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

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


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

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

Ответ 2

Ну, я просто нашел это в docs:

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

Ответ 3

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

например.

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 */