Доступ к переопределенным методам

Задача
Необходимо получить доступ к методам в родительском классе, которые были переопределены в дочернем классе.

Решение
Добавьте префикс parent:: к имени метода:

class shape {
function draw() {
// выводим на экран
}
}
class circle extends shape {
function draw($origin, $radius) {
// проверка данных
if ($radius > 0) {
parent::draw();
return true;
}
return false;
}
}

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

В рассмотренном решении мы переопределяем метод draw() в дочернем классе circle, поскольку необходимо принять специфические для окружности параметры и проверить данные. Однако в данном случае мы еще хотим вызвать базовую функцию shape::draw(), которая фактически выполняет рисование, поэтому вызываем функцию parent::draw()
внутри метода, если значение переменной $radius больше 0.

Префикс parent:: может применяться только внутри класса.


Вызов функции parent::draw() вне класса приведет к синтаксической ошибке. Например, если функция circle::draw() проверяла только радиус, а необходимо было вызвать также и функцию shape::draw(), то ничего бы не получилось:

$circle = new circle;
if ($circle->draw($origin, $radius)) {
$circle->parent::draw();
}

Если необходимо вызвать конструктор, принадлежащий к родительскому объекту, но неизвестно имя родительского класса, вызовите функцию get_parent_class() для динамического определения имени родителя, а затем объедините его с префиксом parent::, чтобы вызвать родительский конструктор:

class circle extends shape {
function circle() {
$parent = get_parent_class($this);
parent::$parent();
}
}

Функция get_parent_class() принимает имя класса или объект, а возвращает имя родителя объекта. Для поддержки общности передавайте $this, что является ссылкой на текущий объект. В этом случае возвращает shape. Затем используйте префикс parent::, чтобы быть уверенным в том, что PHP явно вызывает конструктор родительского класса.

Вызывая $parent() без префикса parent::, вы рискуете вызвать метод класса circle, который подменяет родительское определение.

Вызов функции parent::$parent() может выглядеть несколько странно.


Однако PHP всего лишь заменяет переменную $parent на имя родительского класса. Теперь, поскольку после переменной стоят круглые скобки, PHP знает, что он должен вызвать метод.

Можно жестко прописать вызов функции parent::shape() прямо в конструкторе класса circle:
function circle() {
parent::shape();
}

Однако это не так гибко, как вызов функции get_parent_class(), хотя и быстрее, поэтому если известно, что иерархия объектов не будет изменяться, то такая замена может дать преимущество.

В заключение скажем, что нельзя составлять цепочки ключевых слов parent::, чтобы вернуться к классу прародителя, поэтому parent::parent:: foo() не работает.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Динамическая реализация объекта
Динамическое создание класса
Добавление свойств в базовый объект
Клонирование объектов
Обнаружение методов и свойств объекта

Вернуться в раздел: PHP / 7. Классы и объекты