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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Наследование, и переопределение методов

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
Prizma
Отправлено: 16 Мая, 2016 - 09:58:04
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




Добрый день,
вот такая ситуация сложилась во время разработки:
PHP:
скопировать код в буфер обмена
  1. class A{
  2.     public function getX()
  3.     {
  4.         return 'getX() - ' . $this->calc();
  5.     }
  6.  
  7.     protected function calc()
  8.     {
  9.         return 'A::calc()';
  10.     }
  11. }
  12.  
  13. class B extends A{
  14.     public function getY()
  15.     {
  16.         return 'getY() - ' . $this->calc();
  17.     }
  18.  
  19.     protected function calc()
  20.     {
  21.         return 'B=>' . parent::calc();
  22.     }
  23. }
  24.  
  25. $a = new A();
  26. var_dump($a->getX());
  27. $b = new B();
  28. var_dump($b->getX());
  29. var_dump($b->getY());
Результат:
Цитата:
string 'getX() - A::calc()' (length=18)
string 'getX() - B=>A::calc()' (length=21)
string 'getY() - B=>A::calc()' (length=21)

Проблема в некорректной работе метода getX() если вызывать его из класса B т.к. в нем переопределяется функция calc(). Существует ли ключевое слово для вызова из getX() A::calc() независимо от того был ли метод переопределен?

Пока вижу только такой вариант:
PHP:
скопировать код в буфер обмена
  1. class A{
  2.     public function getX()
  3.     {
  4.         return 'getX() - ' . $this->calc();
  5.     }
  6.  
  7.     protected function calc()
  8.     {
  9.         return $this->_calc();
  10.     }
  11.  
  12.     private function _calc()
  13.     {
  14.         return 'A::calc()';
  15.     }
  16. }
 
My status
 Top
Мелкий Супермодератор
Отправлено: 16 Мая, 2016 - 10:07:36
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Объявите calc как final.


-----
PostgreSQL DBA
 
 Top
Prizma
Отправлено: 16 Мая, 2016 - 10:35:30
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




Мелкий пишет:
Объявите calc как final.
Тогда я не смогу его переопределить, а это необходимо
 
My status
 Top
armancho7777777 Супермодератор
Отправлено: 16 Мая, 2016 - 11:10:29
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




Prizma пишет:
Существует ли ключевое слово для вызова из getX() A::calc()


 
 Top
Prizma
Отправлено: 16 Мая, 2016 - 11:23:13
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




armancho7777777
то что надо, спасибо.

я подумал, что так только статик методы можно вызывать.
 
My status
 Top
OrmaJever Модератор
Отправлено: 16 Мая, 2016 - 12:20:45
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




а как же static::calc() ?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
armancho7777777 Супермодератор
Отправлено: 16 Мая, 2016 - 12:21:58
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




OrmaJever пишет:
а как же static::calc()?

Выполнится метод класса, экземпляром которого является созданный объект:
Спойлер (Отобразить)
Спойлер (Отобразить)



Prizma
Если требуется, чтобы вызывался всегда метод A::calc,
то необходимо запретить переопределение метода в дочерних классах, объявив его финальным, как уже предложил Мелкий.

(Отредактировано автором: 16 Мая, 2016 - 12:49:12)

 
 Top
OrmaJever Модератор
Отправлено: 16 Мая, 2016 - 13:21:05
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




соврал, не static, а self даст нужное поведение
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. class A{
  4.     public function getX()
  5.     {
  6.                 return 'getX() - ' . self::calc();
  7.     }
  8.  
  9.     protected function calc()
  10.     {
  11.         return 'A::calc()';
  12.     }
  13. }
  14.  
  15. class B extends A{
  16.     public function getY()
  17.     {
  18.                 return 'getY() - ' . self::calc();
  19.     }
  20.  
  21.     protected function calc()
  22.     {
  23.         return 'B=>' . parent::calc();
  24.     }
  25. }
  26.  
  27. $a = new A();
  28. var_dump($a->getX());
  29. $b = new B();
  30. var_dump($b->getX());
  31. var_dump($b->getY());


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
armancho7777777 Супермодератор
Отправлено: 16 Мая, 2016 - 14:40:43
Post Id



Активный участник


Покинул форум
Сообщений всего: 4526
Дата рег-ции: Февр. 2011  
Откуда: Москва


Помог: 221 раз(а)




OrmaJever пишет:
self даст нужное поведение

Только потому, что B::calc вызывает A::calc.

(Отредактировано автором: 16 Мая, 2016 - 14:41:12)

 
 Top
OrmaJever Модератор
Отправлено: 16 Мая, 2016 - 15:19:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




armancho7777777 пишет:
Только потому, что B::calc вызывает A::calc.

в смысле?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Prizma
Отправлено: 18 Мая, 2016 - 13:19:35
Post Id



Посетитель


Покинул форум
Сообщений всего: 463
Дата рег-ции: Июнь 2012  
Откуда: Санкт-Петербург


Помог: 5 раз(а)




armancho7777777 пишет:
(new B)->getY(); // B::calc

это уже перебор)) Зачем же я от него тогда наследовал класс A
armancho7777777 пишет:
Prizma
Если требуется, чтобы вызывался всегда метод A::calc,
то необходимо запретить переопределение метода в дочерних классах, объявив его финальным, как уже предложил Мелкий.

Метод B::calc() не может существовать без A::calc() но метод A::calc() так же используется внутри других методов класса A, и когда я начал обращаться к этим методам из класса B, то стал получать не корректные результаты потому, что там использовалось ключевое слово $this для вызова метода calc() и методы класса A стали использовать B::calc(), заменив $this->calc() на A::calc() в методах класса A, всё заработало, как должно Улыбка

(Отредактировано автором: 18 Мая, 2016 - 13:20:32)

 
My status
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB