За последние 24 часа нас посетили 22716 программистов и 1270 роботов. Сейчас ищет 831 программист ...

Как получить информацию объекта класса дочернему классу

Тема в разделе "PHP для новичков", создана пользователем Dasderdas, 8 окт 2022.

  1. Dasderdas

    Dasderdas Новичок

    С нами с:
    29 мар 2022
    Сообщения:
    69
    Симпатии:
    0
    Переменная $parent_var является экземпляром класса ParentClass и хранит в себе name 'Parent'.
    Внутри класса есть функция что получит name по названию переменной.
    Внутри дочернего класса ChildClass Необходимо создать метод в котором нужно получить name переменной $parent_var, то есть воспользоваться функцией родительского класса что позволит его получить.
    Но у меня не выходит это сделать, ошибка 'Uncaught Error: Cannot access parent:: when current class scope has no parent' Как можно исправить?
    PHP:
    1. <?php
    2. class ParentClass {
    3.   function __construct($wname){
    4.     $this -> name = $wname;
    5.   }
    6.   function GetName($fname) {
    7.   global $$fname;
    8.   return $$fname -> name;
    9.     }
    10.   }
    11. $parent_var = new ParentClass('Parent');
    12. //echo $patent_name_1 -> GetName('parent_var'); // Обращение вне классов
    13. class ChildClass {
    14.   function __construct($wname) {
    15.      $this -> name = $wname;
    16.   }
    17.   function GetName($fname) {
    18.      parent::GetName($fname);
    19.   }
    20. }
    21. $child_var = new ChildClass('Child');
    22. echo $child_var -> GetName('parent_var');
    23. ?>
    Ей богу, попытался понятно изложить, но кажись вышло не очень. Надеюсь меня поймут :\
     
  2. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Начнём с того, что ваш ChildClass не имеет "родителя".
     
  3. Dasderdas

    Dasderdas Новичок

    С нами с:
    29 мар 2022
    Сообщения:
    69
    Симпатии:
    0
    Упс.Специально этот код написал для топика, и забыл дописать extends ParentClass.
    И именно если это сделать, он работает хотя вопросом этой темы послужил другой не рабочий код с таким принципом.
    Короче случайно, получился рабочий вариант xD
    Ладно, стыд, позор, вопрос закрыт
     
    #3 Dasderdas, 8 окт 2022
    Последнее редактирование: 8 окт 2022
  4. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Задача, однако, о чём-то вроде "Стратегии".
    Метод дочернего класса (или не дочернего, в общем-то) в качестве параметра получает объект определённого класса и посредством этого объекта вызывает нужный метод и возвращает результат.
    Ко всему прочему нужен интерфейс, который должен реализовывать "родительский" класс.
     
  5. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Телепатов-то нет. А код работает так, как написано, а не придумано :)
     
  6. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Возможно, нечто похожее на:
    https://onlinephp.io/c/dba4a
    PHP:
    1. <?php
    2.  
    3. interface NameGetter
    4. {
    5.    function getSomeName(NameGetter $object);
    6. }
    7.  
    8. class A implements NameGetter
    9. {
    10.    private $someName;
    11.    
    12.    public function __construct(string $name)
    13.    {
    14.      $this->someName = $name;
    15.    }
    16.    
    17.    public function getSomeName(NameGetter $object = null)
    18.    {
    19.      return $this->someName;
    20.    }
    21. }
    22.  
    23. class B extends A
    24. {
    25.    public function getSomeName(NameGetter $object = null)
    26.    {
    27.      return isset($object) ? $object->getSomeName() : $this->someName;
    28.    }
    29. }
    30.  
    31. $foo = new A('Parent');
    32. $boo = new B('MyName');
    33. $someName = $boo->getSomeName($foo);
    34. var_dump($someName, $foo, $boo);
    --- Добавлено ---
    Возможно, в задании указан наследник, чтобы не упоминать про интерфейс :)
     
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    А за каким хреном метод класса лезет в глобальные переменные? Он должен вернуть то, что записано в экземпляре. Доступ к экземпляру внутри методов через $this. Если класс не использует собственные поля, он нафиг значит никому не нужен, и достаточно простой функции
     
    MouseZver нравится это.
  8. Dasderdas

    Dasderdas Новичок

    С нами с:
    29 мар 2022
    Сообщения:
    69
    Симпатии:
    0
    А вот нужно, я недавно создал тему на этот вопрос https://php.ru/forum/threads/ne-rabotaet-kod-s-peremennymi-peremennyx.100308/
    Иначе код работать не будет. Это нужно для самой функции
     
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Логика неправильная. Вон ты устанавливаешь в конструкторе поле (кстати, необъявленные поля - это плохо, в php 8.2 их запретят), и вообще не используешь.
    --- Добавлено ---
    PHP:
    1. class ParentClass {
    2.   protected $name;
    3.   function __construct($wname){
    4.     $this -> name = $wname;
    5.   }
    6.   function GetName() {
    7.       return $this->name;
    8.   }
    9. }
    10.  
    11. class ChildClass extends ParentClass {
    12.    // Переопределять конструктор, который делает то же самое, никому не надо
    13.    // Переопределим GetName, тоже добавив поведение, иначе - тоже нафиг не нужно, как и дочерний класс
    14.    
    15.   function GetName() {
    16.       return parent::GetName() . " from child";
    17.   }
    18. }
    19. $parent_var=new ParentClass('Parent')
    20. $child_var = new ChildClass('Child');
    21.  
    22. echo $child_var->GetName();
    Переменные переменных - это фича, которую нужно использовать только в крайнем случае. Они небезопасные, они хреново читаются, заставляют пересматривать другой код.

    Глобальные переменные - тоже избегаются всячески.
     
    Dasderdas нравится это.
  10. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Dasderdas, вариант упрощенный (теперь без интерфейса) и с исправленной логической ошибкой в определении свойства: песочница.
    С примером получения значения свойства не только от существующего объекта класса-родителя, но и собственного :)
    PHP:
    1. <?php
    2.  
    3. class A
    4. {
    5.    protected $someName;
    6.    
    7.    public function __construct(string $name)
    8.    {
    9.      $this->someName = $name;
    10.    }
    11.    
    12.    public function getSomeName(A $object = null)
    13.    {
    14.      return $this->someName;
    15.    }
    16. }
    17.  
    18. class B extends A
    19. {
    20.    public function getSomeName(A $object = null)
    21.    {
    22.      return isset($object) ? $object->getSomeName() : $this->someName;
    23.    }
    24. }
    25.  
    26. $foo = new A('Parent');
    27. $boo = new B('MyName');
    28. $someName = $boo->getSomeName($foo);
    29. $someName2 = $boo->getSomeName();
    30. var_dump($someName, $someName2, $foo, $boo);
    --- Добавлено ---
    @mkramer, написано, что нужно значение свойства уже существующего объекта класса-родителя:
     
  11. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Dasderdas, уяснил я наконец-то, что в задании требуется :)
    PHP:
    1. class A
    2. {
    3.    protected $someName;
    4.  
    5.    public function __construct(string $name)
    6.    {
    7.      $this->someName = $name;
    8.    }
    9.  
    10.    public function getSomeName()
    11.    {
    12.      return $this->someName;
    13.    }
    14. }
    15.  
    16. class B extends A
    17. {
    18.    public function getSomeName(A $object = null)
    19.    {
    20.      return isset($object) ? $object->getSomeName() : $this->someName;
    21.    }
    22. }
    23. $foo = new A('Parent');
    24. $boo = new B('MyName');
    25. $someName = $boo->getSomeName($foo);
    26. $someName2 = $boo->getSomeName();
    27. var_dump($someName, $someName2, $foo, $boo);
    От предыдущего варианта отличается объявлением метода getSomeName в родительском классе.
    Там не нужны параметры.
     
    Dasderdas нравится это.
  12. Dasderdas

    Dasderdas Новичок

    С нами с:
    29 мар 2022
    Сообщения:
    69
    Симпатии:
    0
    Вау, вот спасибо! Мой вариант более упоротый
     
  13. Александр Петрович

    Александр Петрович Активный пользователь

    С нами с:
    14 ноя 2019
    Сообщения:
    18
    Симпатии:
    0
    Код (Text):
    1. class A
    2. {
    3.     protected static $name;
    4.  
    5.     public function __construct(string $name)
    6.     {
    7.         static::$name = $name;
    8.     }
    9.  
    10.     public function getName()
    11.     {
    12.         return static::$name;
    13.     }
    14.  
    15.     public function getParentName()
    16.     {
    17.         return self::$name;
    18.     }
    19. }
    20.  
    21. class B extends A
    22. {
    23.     protected static $name;
    24. }
    25.  
    26. $a = new A('Aaaaaa');
    27. $b = new B('Bbbbbb');
    28.  
    29. echo $a->getName() . PHP_EOL;           //Aaaaaa
    30. echo $b->getName() . PHP_EOL;           //Bbbbbb
    31. echo $a->getParentName() . PHP_EOL;     //Aaaaaa
    32. echo $b->getParentName() . PHP_EOL;     //Aaaaaa
     
  14. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    @Александр Петрович Очень мило... Инициализировать статическое поле в конструкторе, тем самым перезатерать его с каждым созданным экземпляром