Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Имя дочернего метода вызвавшего родительский
 
 автор: Axxil   (28.11.2007 в 22:10)   письмо автору
 
 

есть классы

<?
class childClass extends parentClass{
  public function 
foo(){
    
/*тра ля-ля*/
    
parent::show();
  }
}

class 
parentClass{
  public function 
show(){
     echo 
$childClassName;
  }
}
?>


Попал в тупик. Как получить название метода дочернего класса в родительском, который из этого дочернего класса вызывается.
В данной ситуации $childClassName = 'foo'; А вообще?

   
 
 автор: Zirkon   (28.11.2007 в 23:46)   письмо автору
 
   для: Axxil   (28.11.2007 в 22:10)
 

А от куда "родитель" знает чьим "родителем" он является? :) Ведь "детей" которые расширяются от данного "родителя" может быть много. :) А у тех "детей" могут быть свои "дети". :) И эти классы не обязательно должны быть в одном файле даже. :)

Что бы что-то подсказать предлагаю Вам описать конкретную ситуацию и постараемся подсказать пути ее решения. :)

   
 
 автор: Axxil   (29.11.2007 в 09:09)   письмо автору
 
   для: Zirkon   (28.11.2007 в 23:46)
 

Куда уж конкретнее то :)
Если описывать всю ситуацию, придётся тянуть слишком много классов. Я специально выделил непонятный момент.

Конкретный метод foo(), конкретного класса childClass вызывает тоже конкретный метод show() конкретного родительского класса parentClass.

В прощлый раз неудачно переменную назвал

<? 
class childClass extends parentClass
  public function 
foo(){ 
    
/*тра ля-ля*/ 
    
parent::show(); 
  } 


class 
parentClass
  public function 
show(){ 
     echo 
$childСlassCallMethodName
  } 

?> 



В этом примере если написать в методе foo()

<?
function foo(){
  
$this->$childСlassCallMethodName 'foo';
  
parent::show();
}
?>


то пример

<?
$child 
= new childClass;
$child->foo();
?>


выведет 'foo';

А мне нужно чтобы автоматически выводилось имя этого метода foo(). Без ручного указания.
что то типа (псевдоязык)

<?
class parentClass
  public function 
show(){ 
     
$childСlassCallMethodName getChildMethodName(); 
     echo 
$childСlassCallMethodName;
  } 

?> 


Т.е. есть какая-нить подобная функция?

   
 
 автор: cheops   (29.11.2007 в 12:20)   письмо автору
 
   для: Axxil   (28.11.2007 в 22:10)
 

Обычно такие методы объявляют в родительском классе как абстрактные - во всю используют их в родительском классе, а реализуют уже в классе-наследнике. Явление это называется полиморфизмом.

   
 
 автор: Axxil   (29.11.2007 в 15:42)   письмо автору
 
   для: cheops   (29.11.2007 в 12:20)
 

Ладно, зайдём с другого бока :)

Родительский класс реализует работу с абстрактным модулем некой системы. Т.е. кокретно метод show() этого родительского класса осуществляет последовательность действий, результатом которой является вывод модуля на экран.
Конкретную реализацию конкретного модуля осуществляет конкретный модуль конкретного класса, наследованного от родительского.
Для неких действий в родительском классе, в методе show() нужно знать имя метода его (этот родительский метод) вызвавшего.

Аналогия.
Есть абстрактный класс, задающий некую фигуру. Выводящий на экран методом paint().
Есть дочерний классы, задающий конкрентные фигуры в методах.
Т.е. есть методы circle, square, bar и т.д.
Так вот, как в методе paint() узнать какая фигура рисуется в данный момент?

   
 
 автор: cheops   (30.11.2007 в 11:15)   письмо автору
 
   для: Axxil   (29.11.2007 в 15:42)
 

Вот именно для этого и существует полиморфизм - у вас все методы, во всех дочерних классах будут называться одинаково, например, show() или paint(), а выполнять они будут действия методов circle, square, bar и т.п. Полиморфизм для того и предназначен, чтобы решить эту проблему - у вас имена методов для всех дочерних классов становятся одинаковыми и определяются абстрактным методом базового класса. Поэтому вы всегда будете знать в базовом классе имя вызываемого метода, а каждый наследник будет обязан реализовать метод именно с таким названием.

   
 
 автор: Axxil   (30.11.2007 в 12:39)   письмо автору
 
   для: cheops   (30.11.2007 в 11:15)
 

Мда... Либо я неправильно объясняю, либо неправильно спроектировал.
Попробую показать конкретную задачу
Любой модуль системы нужно парсить (делать замену переменных в шаблоне, и т.д.) и выводить в нужное месот экрана. Так как эти действия однотипные во всех модулях, то их можно вынести в общий класс, от которого уже наследовать модули.
Т.о. есть некий общий класс который наследуется всеми модулями системы.
В этом классе метод show() отвечает за отображение модуля. Он берёт шаблон. Имя шаблона находится в прямой зависимости от имени метода конкретного модуля news, который вызывается в данный момент.
Так вот, мне надо знать это имя.

<?php
  
class generic_module{
    function 
show(){
      
/*Можно конечно в дочернем классе, в методе прописать специальную переменную
         в которую поместить название метода. (см. ниже)
         Тогда $currentMethod = $this->currentMethod;
          А я хочу автоматом определять $currentMethod...
      */
      
$template file_get_contents($currentMethod);
      
/*some actions*/
      
return $template;
    }
  }
  class 
news extends generic_module{
    function 
getList(){
      
/*some actions*/
      /*Можно в каждом методе явно писать его название
        Типа $this->currentMethod = 'getList'; 
         Но это неудобно и как-то криво      
      */
      
parent::show();
    }
    function 
getOne(){
      
/*some actions*/
      
parent::show();
    }
  }
?>


Может в проектировании что-то я не догоняю?

   
 
 автор: Zirkon   (30.11.2007 в 16:40)   письмо автору
 
   для: Axxil   (30.11.2007 в 12:39)
 

Не понимаю... а почему в каждом таком методе нельзя просто прописать:

$this->show('MethodName');

если уже так хочется "плодить" кучу методов?

И как мне кажется, что-то у вас тут не так... попробуйте поглубже понять что такое ООП, мне кажется, что Вы просто не в теме ООП это все делаете, а типа по аналогии как по старинке, вот только классами. :)

   
 
 автор: kasmanaft   (30.11.2007 в 19:57)   письмо автору
 
   для: Axxil   (30.11.2007 в 12:39)
 

Может быть:

<?php
  
class generic_module{
    function 
show($name){
      echo 
$name;
    }
/*  function show(){
      echo func_get_arg(0);
    }  */
  
}

  class 
news extends generic_module{
    function 
getList(){
      
parent::show(__FUNCTION__);
    }
  }   
  
  
$child = new news;
  
$child->getList();
?>

   
 
 автор: cheops   (01.12.2007 в 13:04)   письмо автору
 
   для: Axxil   (30.11.2007 в 12:39)
 

Я вот что имею в виду
<?php 
  
class generic_module
    abstract function 
getCurrentMethod();
    function 
show(){ 
      
/*Можно конечно в дочернем классе, в методе прописать специальную переменную 
         в которую поместить название метода. (см. ниже) 
         Тогда $currentMethod = $this->currentMethod; 
          А я хочу автоматом определять $currentMethod... 
      */ 
      
$template file_get_contents($this->getCurrentMethod()); 
      
/*some actions*/ 
      
return $template
    } 
  } 
  class 
news extends generic_module
    function 
getList(){ 
      
/*some actions*/ 
      /*Можно в каждом методе явно писать его название 
        Типа $this->currentMethod = 'getList';  
         Но это неудобно и как-то криво       
      */ 
      
parent::show(); 
    } 
    function 
getOne(){ 
      
/*some actions*/ 
      
parent::show(); 
    } 
  } 
?>

А метод getCurrentMethod(), который необходимо будет перегружать в каждом наследнике, и в базовый класс не нужно будет помещать информацию о наследниках (т.е. не потребуется нарушение инкапсуляции).

   
 
 автор: cheops   (01.12.2007 в 13:06)   письмо автору
 
   для: cheops   (01.12.2007 в 13:04)
 

А лучше вообще сделайте метод show() абстрактным и реализуйте его в наследниках как вам самим захочется, хоть с исопльзованием file_get_contents(), хоть без.

   
 
 автор: Axxil   (01.12.2007 в 22:54)   письмо автору
 
   для: cheops   (01.12.2007 в 13:06)
 

Спасибо всем. Я понял.
Все понимаю все эти методы реализации. Сейчас, с нуля я бы так и сделал.
Просто система уже написана и наследников много и не хочется лезть в каждый из них чтобы прописывать новые методы. Просто понадобилось расширить функциональность (прикрутить "умный" кеш). И я хотел попроще. Ну раз уж автоматом не получается определять метод, то видимо придётся всё-таки лезть в каждого наследника :(

PS В том то и дело, что я думал что знаю ООП, когда начал писать свой фреймворк. Сейчас понимаю что не совсем понял основные фишки. Поэтому грядёт глубокий рефакторинг системы :(((
Хорошо что основа прочная...
Так что всем очень рекомендую сначала хорошенько понять ООП, прежде чем приступать к написанию "супер-системы" :). На своей шкуре почувствовал. Век живи, век учись.

   
 
 автор: cheops   (02.12.2007 в 12:32)   письмо автору
 
   для: Axxil   (01.12.2007 в 22:54)
 

Это нормально для FrameWork-ов - их раза по три переписывают, зато потом долго и плодотворно используют.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования