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. Prizma - 16 Мая, 2016 - 09:58:04 - перейти к сообщению
Добрый день,
вот такая ситуация сложилась во время разработки:
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. }
2. Мелкий - 16 Мая, 2016 - 10:07:36 - перейти к сообщению
Объявите calc как final.
3. Prizma - 16 Мая, 2016 - 10:35:30 - перейти к сообщению
Мелкий пишет:
Объявите calc как final.
Тогда я не смогу его переопределить, а это необходимо
4. armancho7777777 - 16 Мая, 2016 - 11:10:29 - перейти к сообщению
Prizma пишет:
Существует ли ключевое слово для вызова из getX() A::calc()


PHP:
скопировать код в буфер обмена
  1. parent::calc()
5. Prizma - 16 Мая, 2016 - 11:23:13 - перейти к сообщению
armancho7777777
то что надо, спасибо.

я подумал, что так только статик методы можно вызывать.
6. OrmaJever - 16 Мая, 2016 - 12:20:45 - перейти к сообщению
а как же static::calc() ?
7. armancho7777777 - 16 Мая, 2016 - 12:21:58 - перейти к сообщению
OrmaJever пишет:
а как же static::calc()?

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

PHP:
скопировать код в буфер обмена
  1. (new B)->getY(); // B::calc


Prizma
Если требуется, чтобы вызывался всегда метод A::calc,
то необходимо запретить переопределение метода в дочерних классах, объявив его финальным, как уже предложил Мелкий.
8. OrmaJever - 16 Мая, 2016 - 13:21:05 - перейти к сообщению
соврал, не 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());
9. armancho7777777 - 16 Мая, 2016 - 14:40:43 - перейти к сообщению
OrmaJever пишет:
self даст нужное поведение

Только потому, что B::calc вызывает A::calc.
10. OrmaJever - 16 Мая, 2016 - 15:19:30 - перейти к сообщению
armancho7777777 пишет:
Только потому, что B::calc вызывает A::calc.

в смысле?
11. Prizma - 18 Мая, 2016 - 13:19:35 - перейти к сообщению
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, всё заработало, как должно Улыбка

 

Powered by ExBB FM 1.0 RC1