Привидение классов php

254
03 июня 2018, 18:00
class A {
  public function foo() {
  }
}
class B extends A {
}

Как после создания класса B представить его классом A

$b = new B();

Нужно "превратить", "откатить", "представить" классом A. Потом выполнить метод foo() ВАЖНО: Вызывать $b->foo() не нужно пока он не превратился в A.

parent::foo()

Не помогает

Answer 1
  1. Объект какого-то класса не может "превратиться" в объект другого класса. Тип объекта задается при его создании.
  2. Объект класса (ссылка на объект) может быть помещен в переменную любого типа ниже по иерархии наследования. Например, объект типа В может быть помещен в переменную типа А.
  3. Набор методов, которые можно будет вызывать для объекта определяется типом переменной, в которую помещен объект, а не самим объектом. Набор методов определяется интерфейсами, которые имплементирует класс, который задан в типе переменной.
  4. Если объект помещен в нетипизированную переменную (object), то можно вызывать любой публичный метод объекта. Это называется поздним связыванием. Т.е. на этапе компиляции система вообще не знает о том, какой метод будет тут выполняться и есть ли реализация этого метода в объекте, помещенном в данную переменную. Во время выполнения будет сделан поиск в наборе методов, имплементируемых объектом, помещенным в переменную и, если нужный метод будет найден, то он будет выполнен. Если не найден - будет ошибка времени выполнения.
  5. Содержимое метода, которое будет выполнено при вызове, определяется типом объекта, который помещен в переменную. А не типом переменной, в которую помещен объект.

Из сказанного выше следует, что вызвать реализацию метода foo определенную в классе А можно в случаях:

  1. Если метод foo не перекрыт в наследнике, то его можно вызвать и для переменной типа В и для переменной типа А. Разницы нет. Все равно будет выполнена реализация А.
  2. Если метод foo перекрыт в наследнике, то реализацию метода, сделанную в классе А напрямую вызывать не получится. Независимо от того, какой тип переменной задан А или В, будет выполняться реализация созданного объекта - если создан объект типа В, то будет выполняться реализация класса В.
  3. Если все же необходимо выполнять именно реализацию, определенную в классе А для объекта класса В, то можно пойти тремя путями:

Первый вариант - оставить метод foo в классе В не перекрытым, тогда будет выполняться реализация А, а нужную функциональность для класса В реализовать в методе fooB, в котором уже вызывать parent::foo().

Второй вариант - определить в классе В новый метод fooA в котором вызывать parent::foo()

Последний, самый правильный вариант - выделить общую функциональность для всех классов в отдельный метод fooBase в классе А. И вызывать по необходимости этот метод в нужном меcте в классах наследниках или определить его интерфейсным и вызывать где нужно в программе.

PS. Я не очень хорошо знаю ООП именно в PHP. Возможно, в PHP есть еще другие варианты вызова метода предка типа extension методов. Если такое есть, то пусть дополнят мой ответ гуру от PHP.

READ ALSO
Ошибка composer Your requirements could not be resolved to an installable set of packages

Ошибка composer Your requirements could not be resolved to an installable set of packages

Установил composer по инструкции со офсайта

370
OpenCart текущая версия сайта

OpenCart текущая версия сайта

Есть сайт на OpencartМне нужно изменить 2 класса на странице каталога товаров

173
При вызове return Cache::has('user-is-online-' . $this->id); Выдает ошибку Class 'League\Flysystem\Cached\Storage\AbstractCache' not found

При вызове return Cache::has('user-is-online-' . $this->id); Выдает ошибку Class 'League\Flysystem\Cached\Storage\AbstractCache' not found

Всем привет! Весь интернет перерыл не могу найти решение данной проблемы У меня проект на laravel 56 сервер NGINX , хочу сделать чтоб было видно когда...

171
Уведомление курса валют

Уведомление курса валют

Вопрос как сделать уведомление на сайте при изменении курса валют? И также интересно сделать график изменения

197