Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Вызвать базовый метод в обход полиморфизму
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Вызвать базовый метод в обход полиморфизму

Страниц (1): [1]
 

1. Panoptik - 06 Сентября, 2013 - 16:20:16 - перейти к сообщению
всем привет

вот случилось у меня. и что-то не соображу
есть 2 класса: родительский и наследник

PHP:
скопировать код в буфер обмена
  1.  
  2. class A {
  3.  
  4.   public function f($a) {
  5.     return $a;
  6.   }
  7.  
  8.   public function myProblemHere() {
  9.      //some code here
  10.  
  11.      // здесь я хочу получить 3 а не 5 вызвав метод именно этого класса а не дочернего
  12.      $a = $this->f(3);
  13.  
  14.      //some code here
  15.   }
  16.  
  17. }
  18.  
  19. class B extends A {
  20.  
  21.   public function f($a) {
  22.      return $a + 2;
  23.   }
  24.  
  25. }
  26.  
  27.  


кто что посоветует?
2. Мелкий - 06 Сентября, 2013 - 16:26:05 - перейти к сообщению
Решение немного совсем не очевидное, но:

Нет, это не вызов статического метода.

Тем не менее, это штатное поведение, в мануале краткого очерка заслужило: http://www.php.net/manual/ru/key...-nekudotayim.php
3. Panoptik - 06 Сентября, 2013 - 16:29:43 - перейти к сообщению
вообще спасибо
оказалось, зря беспокоился и метод нигде не переопределяется, но в продолжение интересно темы хотелось бы поинтересоваться о следующем

при этом не будет никаких ворнингов?
интересно как оно транслятор определяет что нужно вызывать не статический метод?
4. DlTA - 06 Сентября, 2013 - 16:31:02 - перейти к сообщению
Panoptik пишет:
// здесь я хочу получить 3 а не 5 вызвав метод именно этого класса а не дочернего
     $a = $this->f(3);
 
ошибка в проектировании, плохой тон разрабатывать класс который для наследования, вопрос о том чей метод будет вызываться должен решать наследник а не родитель, и все сразу станет на свои места
(Добавление)
http://www.php.net/manual/ru/keyword.parent.php
5. Мелкий - 06 Сентября, 2013 - 16:41:03 - перейти к сообщению
Нет, всё штатно, никаких предупреждение.
В том числе и $this доступен в вызванном методе.

А определяется, по-видимому, просто: если существует в классе не статичный метод с таким названием, то он и вызывается как метод объекта. И только если указано у метода static - он вызывается как статичный.
6. EuGen - 06 Сентября, 2013 - 16:41:17 - перейти к сообщению
Это - один из примеров во-первых, плохого дизайна приложения, а, во-вторых, плохой модели ООП в PHP.
Разыменование статических методов как обычных и наборот - работает в PHP (и не вызовет ошибки, но, например, при обращении к $this произойдёт ошибка времени исполнения, если метод вызван как статический).
Происходит это потому, что в PHP нет статических методов. Они все - обычные, просто статические имеют соответствующий флаг, и всё - это и есть отличие в результирующем после интерпретации опкоде. Из-за этого, например, невозможно инициировать вызов __callStatic, если происходит обращение к существующему нестатическому методу через оператор :: (вместо ожидаемого вызова __callStatic произойдёт вызов самого метода).
Решение через ::self неявно опирается на такое свойство PHP. Корректнее делать это через parent, ещё корректнее - соблюдать определённую Вами же иерархию классов и понимать, что $this - это экземпляр текущего класса, определённый в данный момент, и, соответственно, действовать сообразно этому.
7. Panoptik - 06 Сентября, 2013 - 17:00:43 - перейти к сообщению
EuGen, спасибо за развернутый ответ. думаю остальным тоже будет познавательно

на счет архитектуры как упоминал выше - зря беспокоился, и этот заветный метод никем не переопределяется

но про использование static открыл для себя новое
8. LIME - 06 Сентября, 2013 - 17:02:58 - перейти к сообщению
EuGen как же вызывается статический метод если не было инстанциировано ни одного объекта?
9. EuGen - 06 Сентября, 2013 - 17:09:39 - перейти к сообщению
LIME
Как обычно. Тело метода хранится статически. Это объекты имеют данные, хранимые по смещениям своих экземпляров (и привязывающиеся к методу в момент вызова)
10. Panoptik - 06 Сентября, 2013 - 17:15:02 - перейти к сообщению
я уже перестал понимать суть. Где можно подробно и по возможности понятно почитать о том как на самом деле работает ООП (в частности классы) в php ?
11. LIME - 06 Сентября, 2013 - 17:15:39 - перейти к сообщению
то есть при вызове метода не происходит выделение динамической памяти и переноса в нее кода как при вызовах обычных ф-ций?
тогда скорее в PHP все методы статические
12. EuGen - 06 Сентября, 2013 - 17:21:00 - перейти к сообщению
Panoptik пишет:
Где можно подробно и по возможности понятно почитать о том как на самом деле работает ООП (в частности классы) в php ?

К сожалению, сходу не смогу сказать ресурсы, где бы можно было это прояснить для себя с учётом обоих требований. Все ресурсы, подозреваю, будут англоязычными. Я узнал многие подобные вещи из конференции SO, общаясь в том числе с разработчиками некоторых известных расширений PHP (в общем случае такие вопросы уходят за рамки обычных страниц руководств).

 

Powered by ExBB FM 1.0 RC1