За последние 24 часа нас посетили 51593 программиста и 1760 роботов. Сейчас ищут 697 программистов ...

Защищенный метод родительского класаа -> публичный дочерн

Тема в разделе "PHP для новичков", создана пользователем DZEN, 26 фев 2009.

  1. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Очень надо сделать возможность вызывать защищённые методы класса из дочернего.

    Суть проблемы - в родительском классе около двух сотен (это примерно) защищённых функций которые надо вызывать из дочернего класса, не изменяя родительский класс. Переписывать каждую функцию внутри дочернего класса просто муторно. Хотя этим собственно говоря я сейчас и занимаюсь, но вдруг найдуться умельцы которые объяснят мне глупому как же это сделать.
    PHP:
    1. <?php
    2. class ParentClass
    3. {
    4.     protected function ParentFunction($variable)
    5.     {
    6.         echo $variable;
    7.     }
    8. }
    9.  
    10. class ChildClass extends ParentClass
    11. {
    12.     private $ParentClass;
    13.     public function __construct()
    14.     {
    15.         $this->ParentClass=new ParentClass();
    16.     }
    17.     public function __call($function,$arguments)
    18.     {
    19.         //Первый вариант
    20.         $this->call_user_func($function,$arguments);
    21.     }
    22.     public function __call($function,$arguments)
    23.     {
    24.         //Второй вариант
    25.         $ParentClass=new ReflectionMethod('ParentClass',$function);
    26.         return $ParentClass->invokeArgs($this->ParentClass,$arguments);
    27.     }
    28. }
    29. $c=new ChildClass();
    30. $c->ParentFunction("It works!");
    31. ?>
    Вот такие у меня были неудачные попытки...
    Второй метод - позорная попытка вызывать методы, если родительский класс только один.
     
  2. shreck

    shreck Активный пользователь

    С нами с:
    7 авг 2007
    Сообщения:
    479
    Симпатии:
    0
    Адрес:
    Россия, Саратов
    Почитай про наследование. Это как раз твой случай!
     
  3. akrinel

    akrinel Активный пользователь

    С нами с:
    26 янв 2009
    Сообщения:
    955
    Симпатии:
    1
    Адрес:
    Spb
  4. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    костыль:
    PHP:
    1. <?php
    2. class A{
    3. protected function aaa($aa) {
    4. echo 'a='.$aa;
    5. }
    6. }
    7.  
    8.  
    9. class B extends A{
    10. public function mycall($function,$arguments)     {
    11. call_user_func(array($this,$function),$arguments);
    12. }
    13.  
    14. }
    15. $a = new A;
    16. $b = new B;
    17. echo $b->mycall('aaa','gggg');
    18. ?>
     
  5. shreck

    shreck Активный пользователь

    С нами с:
    7 авг 2007
    Сообщения:
    479
    Симпатии:
    0
    Адрес:
    Россия, Саратов
    Сори...не понял сути проблемы!
     
  6. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    только у меня это статика, а не с экземпляром класса. и вообще непонятно как работает )), надо бы передавать имя класса, а не $this
     
  7. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    PHP:
    1. <?php
    2. class A {
    3.     protected function hello($who) {
    4.         print 'Hello, ' . $who . '?';
    5.     }
    6. }
    7.  
    8. class B extends A {
    9.     public function __call($name, $args) {
    10.         return call_user_func_array(array($this, $name), $args);
    11.     }
    12. }
    13.  
    14. class C {
    15.     private $b;
    16.  
    17.     public function __construct(B $b) {
    18.         $this->b = $b;
    19.     }
    20.  
    21.     public function __call($name, $args) {
    22.         $this->b->__call($name, $args);
    23.     }
    24. }
    25.  
    26. $c = new C(new B());
    27. $c->hello('world');
     
  8. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Sergey89а зачем такие извращения, тогда уж просто прозрачно создавать внутри детки родителя и фазамакерствовать.
    но все равно это статика.
     
  9. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Если сделать, как ты говоришь, то __call ребёнка не перехватит вызов защищённого метода. Не нужно забывать, что класс B наследуется от A.

    а вот этого не понял. поясни.
     
  10. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Sergey89
    ок, ну все равно неявно вызывать внутри (псевдо)родителя и с ним изгаляться.

    статика - что ты вызываешь статический метод, неспособный работать с данными этого экземпляра.
     
  11. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    почему же?

    PHP:
    1. <?php
    2. class A {
    3.     private $hello = 'Hello, %s!';
    4.  
    5.     public function __construct($hello) {
    6.         $this->hello = $hello;
    7.     }
    8.  
    9.     protected function hello($who) {
    10.         printf($this->hello, $who);
    11.     }
    12. }
    13.  
    14. class B extends A {
    15.     public function __call($name, $args) {
    16.         return call_user_func_array(array($this, $name), $args);
    17.     }
    18. }
    19.  
    20. class C {
    21.     private $b;
    22.  
    23.     public function __construct(B $b) {
    24.         $this->b = $b;
    25.     }
    26.  
    27.     public function __call($name, $args) {
    28.         $this->b->__call($name, $args);
    29.     }
    30. }
    31.  
    32. $c = new C(new B('Hello, %s!'));
    33. $c->hello('world');
     
  12. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    я вот тож не пойму какие проблемы вызвать метод унаследованный от родителя. protected как раз это позволяет.
     
  13. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Внимательно посмотри на контекст в котором вызвать надо :) Из дочернего класса вызывать не проблема.
     
  14. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    ок, тогда так:
    PHP:
    1. <?php
    2. class C {
    3.       private $b;
    4.  
    5.       public function __construct($h) {
    6.          $this->b = new B($h);
    7.       }
    8.  
    9.       public function __call($name, $args) {
    10.           $this->b->__call($name, $args);
    11.       }
    12.   }
    13.  
    14.   $c = new C('Hello, gg!');
    15.   $c->hello('world');
    16. ?>
    но __call можно вынести в A
     
  15. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Если нужно поменять поведение только класса B, то можно и так сделать, но я не люблю связывать классы подобным образом.

    Если не считать этого условия
    то можно и вынести :)
     
  16. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Ну вот. Только вчера колдовали, а сегодня пришло такое известие
    Новое поведение __call в PHP 5.2.9, теперь он может перехватывать вызовы к private и protected методам. Теперь класс C можно выкинуть и переложить всю ответственность на класс B.
     
  17. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Жду апдейт хостинга :twisted: .
     
  18. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    А чего ждать то? :) Использую мой вариант, а потом просто замени new C(new B()) на new B().
     
  19. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Я вообще жду php 6. Ведь в 5.3 уже есть __callStatic() и пространства имен. Пространства имен это вообще манна небесная, глядишь php скоро объектно-ориентированным языком программирования станет...
     
  20. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    В php 6 только поддержку юникода и добавят, весь новый функционал в php 5 будет реализован.
    да уже давно как стал
     
  21. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
  22. neyr00n

    neyr00n Активный пользователь

    С нами с:
    29 ноя 2007
    Сообщения:
    106
    Симпатии:
    0
    "вечный спор, чтоже лучше. винда или линукс, фар или нортон коммандер. моё или твоё...". ну и так далее.