воскресенье, 24 февраля 2013 г.

Обязательные конструкторы

Объектно-ориентированное программирования в PHP такое... объектно-ориентированное...

Пусть есть базовый класс BaseClass. Создаём его потомка - класс ChildClass. Создаём конструктор и "на автомате" вызываем конструктор базового класса.
class BaseClass { }

class ChildClass extends BaseClass {
    public function __construct() {
        parent::__construct();
        // какой-то код
    }
}

$obj = new ChildClass();
Если в базовом классе конструктор не объявлен явно, то мы рискуем получить сюрприз в виде "PHP Fatal error: Cannot call constructor". Чтобы избавиться от ошибки, либо не вызываем конструктор предка, что в большинстве случаев плохая практика, либо пишем пустой конструктор в базовом классе.

В коде ниже ошибка уже не появляется.
class BaseClass {
    public function __construct() { }
}

class ChildClass extends BaseClass {
    public function __construct() {
        parent::__construct();
        // какой-то код
    }
}

$obj = new ChildClass();
Аналогичная ситуация с деструктором. Не хочешь проблем - пиши пустой метод. Мелкое неудобство, но не позволяет полностью скрыть реализацию базового класса. Всегда нужно смотреть в код и проверять наличие конструкторов/деструкторов. Отдельной интриги добавляют приватные конструкторы и деструкторы.

Причина такого поведения понятна. То, что в PHP называется конструктором, на самом деле - обычная функция инициализации. Но при этом абсолютно непонятно, что делать, чтобы не допускать связанных с этим ошибок. Остаётся быть внимательным, смириться и пользоваться тем, что есть.