Являются ли конструкторы абстрактного класса неявным образом вызваны при создании экземпляра производного класса?
Возьмем этот пример:
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
Ответы
Ответ 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 */