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 » » Объектно-ориентированное программирование » Помогите понять интерфейсы

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

1. Bio man - 25 Сентября, 2011 - 19:21:07 - перейти к сообщению
Привет форумчане! Читал мануал на оф сайте про интерфейсы, читал книгу где используются интерфейсы но не как не могу понять для чего они нужны! Интерфейс это скелет а мясо наращивает класс, но зачем нужен интерфейс??? допустим я не вижу разницы в следующем:
PHP:
скопировать код в буфер обмена
  1.  
  2. interface A {
  3.    public function name($name);
  4.    public function surname($surname);
  5. }
  6.  
  7. class person implements A {
  8.   public function name($name) {
  9.      return 'My name is '.$name;
  10.   }
  11.   public function surname($surname) {
  12.      return ' and surname is '.$surname;
  13.   }
  14. }
  15.  
  16. $obj = new person();
  17. echo $obj->name('Vasja'), $obj->surname('Pupkin');
  18.  


и
PHP:
скопировать код в буфер обмена
  1.  
  2. class person {
  3.   public function name($name) {
  4.      return 'My name is '.$name;
  5.   }
  6.   public function surname($surname) {
  7.      return ' and surname is '.$surname;
  8.   }
  9. }
  10.  
  11. $obj = new person();
  12. echo $obj->name('Vasja'), $obj->surname('Pupkin');
  13.  


помогите понять интерфейсы, очень надо
2. caballero - 25 Сентября, 2011 - 19:32:30 - перейти к сообщению
если они тебе не понадобились значит не нужны - чего напрягатся
когда наберешся опыта и будешь делать проекты посложнее тогда понадобятся
а может и нет - в PHP интерфейсы не так востребованы как в С++ bkb Офмф


Цитата:
Интерфейс это скелет а мясо наращивает класс, но зачем нужен интерфейс?


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

Цитата:
допустим я не вижу разницы в следующем:


на одном классе конечно разницы нет
3. DlTA - 25 Сентября, 2011 - 19:35:34 - перейти к сообщению
Bio man
почитайте про наследование
может прояснится
4. caballero - 25 Сентября, 2011 - 19:43:52 - перейти к сообщению
он интерфейсы спрашивает а не наследование
5. OrmaJever - 25 Сентября, 2011 - 19:51:38 - перейти к сообщению
хотел тоже чтото написать но моя мысль свелась к следуйщему
caballero пишет:
если они тебе не понадобились значит не нужны - чего напрягатся

Ничего свехестественого они не дают, и используются редко.
6. Bio man - 25 Сентября, 2011 - 19:51:48 - перейти к сообщению
ну наследование я понел, это расширение базового класса. и как я понел интерфейс это своего рода шаблон для класса и актуален только тогда когда дополнением занимается сторонний разработчик. а как быть с множественным наследованием? читал, что класс не поддерживает множественное наследование и для решения этой проблемы используют интерфейсы. типо
PHP:
скопировать код в буфер обмена
  1. class A implements B, C, D, ... {}
я так понимаю что в классе А должны быть реализованы все методы наследованных интерфейсов?
7. DlTA - 25 Сентября, 2011 - 20:07:39 - перейти к сообщению
)) чемто костыль напоминает, типа не продумали сразу так давай теперь прикинемся трехногим
8. caballero - 25 Сентября, 2011 - 20:17:38 - перейти к сообщению
Цитата:
я так понимаю что в классе А должны быть реализованы все методы наследованных интерфейсов?

правильно
множественное наследование есть только в C++ из распространненных языков
в PHP5.4 появился костыыль под названием трейты
можно засунуть функцию в класс со стороны не объявляя ее в классе


в любом случае интерфейсы - механизм которым нужно уметь пользоватся
если не знаешь как пользоватся значит в твоих проектах они не нужны
обычно юзаются в сложных системмах типа фреймворков CMS и т.д.

когда будешь писать что то подобное тогда и узнаешь что таклое интерфейс и зачем он
объяснять на пальцах бесполезно
9. Bio man - 25 Сентября, 2011 - 20:18:09 - перейти к сообщению
DlTA пишет:
)) чемто костыль напоминает, типа не продумали сразу так давай теперь прикинемся трехногим
не помог твой ответ.
Цитата:
я так понимаю что в классе А должны быть реализованы все методы наследованных интерфейсов?
вот что хочу уточнить
(Добавление)
всем спасибо, все понел
10. Champion - 25 Сентября, 2011 - 20:40:39 - перейти к сообщению
К тому, что написал caballero, можно дабавить такую вещь.
Вы пишете проект и хотите предоставить сторонним разработчикам большую свободу в плане замены стандартных, разработанных Вами модулей, на ихние новые.
Допустим, у Вас есть модуль, реализованный классом А, расширяющим интерфейс I. Тогда для корректной разработке нового класса А в замен Вашему, разработчик тоже будет обязан реализовать то, что предлагает I.
Конечно, его ничто не обязывает так поступать, но это в его интересах, т.к. если он не реализует какой-нибудь из методов интерфейса, то что-то где-то может не сработать. А так разработчик четко знает, что ему надо реализовать
11. Bio man - 25 Сентября, 2011 - 20:52:53 - перейти к сообщению
ага. вот еще вопрос. в данном скрипте если стереть "implements Iterator" то ничего работать не будет, тоесть выведет пустую страницу, иначе все хорошо работает. почему так происходит?
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. ////////////////////////////////////////////////////////////////////
  3. class MySQLResultSet implements Iterator{
  4.   //data members
  5.   private $strSQL;
  6.   private $databasename;
  7.   private $connection;
  8.   private $result;
  9.   private $valid;
  10.   private $currentrow;
  11.   private $key;
  12.   //programmer defined error numbers
  13.   //in range not used by MySQL
  14.   const INDETERMINATE_TOTAL_NUMBER = 5001;
  15.   const UNNECESSARY_SQL_CALC_FOUND_ROWS = 5002;
  16.   const NOT_SELECT_QUERY = 5003;
  17. ////////////////////////////////////////////////////////////////////
  18. //constructor
  19. ////////////////////////////////////////////////////////////////////
  20.   public function __construct( $strSQL, $databasename, $connection ){
  21.     $this->strSQL = $strSQL;
  22.     $this->connection = $connection;
  23.     $this->databasename = $databasename;
  24.     if(!mysql_selectdb($databasename, $connection)){
  25.       throw new MySQLException(mysql_error(), mysql_errno());
  26.     }
  27.     if(!$this->result = mysql_query($strSQL, $connection)){
  28.       throw new MySQLException(mysql_error(), mysql_errno());
  29.     }
  30.     //check if contains SQL_CALC_FOUND_ROWS
  31.     if (stristr($strSQL,"SQL_CALC_FOUND_ROWS")){
  32.       $msg = "No need to use SQL_CALC_FOUND_ROWS.";
  33.       throw new MySQLException($msg, self::UNNECESSARY_SQL_CALC_FOUND_ROWS);
  34.     }
  35.     //initialize values (not necessary for foreach)
  36.     $this->rewind();
  37.   }
  38. ////////////////////////////////////////////////////////////////////
  39. //destructor
  40. ////////////////////////////////////////////////////////////////////
  41.   public function __destruct(){
  42.     $this->close();
  43.   }
  44. ////////////////////////////////////////////////////////////////////
  45. // public methods
  46. ////////////////////////////////////////////////////////////////////  
  47.   public function getDatabaseName(){
  48.     return $this->databasename;
  49.   }
  50. ////////////////////////////////////////////////////////////////////
  51.   public function getNumberColumns(){
  52.     return mysql_num_fields($this->result);
  53.   }
  54. ////////////////////////////////////////////////////////////////////
  55. //For select queries only
  56. ////////////////////////////////////////////////////////////////////
  57.   public function getNumberRows(){
  58.     return mysql_num_rows($this->result);
  59.   }
  60. ////////////////////////////////////////////////////////////////////
  61.   public function getInsertId(){
  62.     return mysql_insert_id( $this->connection);
  63.   }
  64. ////////////////////////////////////////////////////////////////////
  65. //Calculate total number of records if a limit clause present
  66. //Useful for calculating number of pages in versions < 4
  67. //Unreliable results if DISTINCT used
  68. ////////////////////////////////////////////////////////////////////
  69.   public function getUnlimitedNumberRows(){
  70.     $number = 0;
  71.     $versionnumber = $this->findVersionNumber();
  72.     //only need leftmost number
  73.     $version = substr($versionnumber,0,1);
  74.     //CHECK SELECT
  75.     if (!$this->checkForSelect()){
  76.       $msg = "Illegal method call - not a SELECT query";
  77.       throw new MySQLException($msg, self::NOT_SELECT_QUERY);
  78.     }
  79.     //check for limit clause
  80.     $tempsql = strtoupper($this->strSQL);
  81.     $end = strpos($tempsql,"LIMIT");
  82.     if ($end === false){ //no limit clause
  83.       $number = mysql_num_rows($this->result);
  84.     }
  85.     elseif($version < 4){
  86.       $number = $this->countVersionThree($end);
  87.     }else{ //version 4 or higher use SQL_CALC_FOUND_ROWS function
  88.       $number = $this->countVersionFour();
  89.     }
  90.     return $number;
  91.   }
  92. ////////////////////////////////////////////////////////////////////
  93.   public function getFieldNames(){
  94.     $fieldnames = array();
  95.     if(isset($this->result)){
  96.       $num = mysql_numfields($this->result);
  97.       for($i = 0; $i < $num; $i++){
  98.         if (!$meta = mysql_fetch_field($this->result, $i)){
  99.           throw new MySQLException(mysql_error(), mysql_errno());
  100.         }else{
  101.           $fieldnames[$i]= $meta->name;
  102.         }
  103.       }
  104.     }
  105.     return $fieldnames;
  106.   }
  107. ////////////////////////////////////////////////////////////////////
  108.   public function findVersionNumber(){
  109.     //mysql_get_server_info
  110.     return mysql_get_server_info($this->connection);
  111.   }
  112. ////////////////////////////////////////////////////////////////////
  113. //Iterator methods that must be implemented
  114. ////////////////////////////////////////////////////////////////////
  115.   public function current (){
  116.     return $this->currentrow;
  117.   }
  118. ////////////////////////////////////////////////////////////////////
  119.   public function key (){
  120.     return $this->key;
  121.   }
  122. ////////////////////////////////////////////////////////////////////
  123.   public function next (){
  124.     if($this->currentrow = mysql_fetch_array($this->result)){
  125.       $this->valid = true;
  126.       $this->key++;
  127.     }else{
  128.       $this->valid = false;
  129.     }
  130.   }
  131. ////////////////////////////////////////////////////////////////////
  132.   public function rewind (){
  133.     if($num = mysql_num_rows($this->result) > 0){
  134.       if(mysql_data_seek($this->result, 0)){
  135.         $this->valid = true;
  136.         $this->key = 0;
  137.         $this->currentrow = mysql_fetch_array($this->result);
  138.       }
  139.     }else{
  140.       $this->valid = false;
  141.     }
  142.   }
  143. ////////////////////////////////////////////////////////////////////
  144.         public function valid (){
  145.     return $this->valid;
  146.   }
  147. ////////////////////////////////////////////////////////////////////
  148. //private methods
  149. ////////////////////////////////////////////////////////////////////  
  150.   private function checkForSelect(){
  151.     $bln = true;
  152.     $strtemp = trim(strtoupper($this->strSQL));
  153.     if(substr($strtemp,0,6)!= "SELECT"){
  154.       $bln = false;
  155.     }
  156.     return $bln;  
  157.   }
  158. ////////////////////////////////////////////////////////////////////
  159.   private function close(){
  160.     if(isset($this->result)){
  161.       mysql_free_result($this->result);
  162.       unset($this->result);
  163.     }
  164.   }
  165. ////////////////////////////////////////////////////////////////////  
  166.   private function countVersionFour(){
  167.     $tempsql = trim($this->strSQL);
  168.     //insert SQL_CALC_FOUND_ROWS
  169.     $insertstr = " SQL_CALC_FOUND_ROWS ";
  170.     //already know it starts with "SELECT"
  171.     $tempsql = substr_replace($tempsql, $insertstr, 6, 1);
  172.     if(!$rs = mysql_query($tempsql, $this->connection)){
  173.       throw new MySQLException(mysql_error(), mysql_errno());
  174.     }
  175.     $tempsql = "SELECT FOUND_ROWS()";
  176.     if(!$rs = mysql_query($tempsql)){
  177.       throw new MySQLException(mysql_error(), mysql_errno());
  178.     }
  179.     $row = mysql_fetch_row($rs);
  180.     $number = $row[0];
  181.     //dispose of $rs
  182.     mysql_free_result($rs);
  183.     return $number;
  184.   }
  185. ////////////////////////////////////////////////////////////////////  
  186.   private function countVersionThree($end){
  187.     $tempsql = strtoupper($this->strSQL);
  188.     //check for DISTINCT - will throw things off
  189.     if(!strpos($tempsql,"DISTINCT")){
  190.       //create recordset
  191.       $start = strpos($tempsql,"FROM");
  192.       $numchars = $end-$start;
  193.       $countsql = "SELECT COUNT(*) ";
  194.       $countsql .= substr($this->strSQL, $start, $numchars);
  195.       if(!$rs=mysql_query($countsql, $this->connection)){
  196.         throw new MySQLException( mysql_error(), mysql_errno());
  197.       }
  198.       $row = mysql_fetch_row($rs);
  199.       $number = $row[0];
  200.       //dispose of $rs
  201.       mysql_free_result($rs);
  202.     }else{
  203.       $msg = "Using keyword DISTINCT, ".
  204.          "calculate total number manually.";
  205.       //must use self - not a property
  206.       throw new MySQLException($msg, self::INDETERMINATE_TOTAL_NUMBER);
  207.     }
  208.     return $number;
  209.   }
  210. }//end class
  211. ?>
  212.  
12. Champion - 25 Сентября, 2011 - 21:13:57 - перейти к сообщению
Надо включить показ ошибок, тогда будет видно, почему. display_errors on и error_reporting E_ALL
(Добавление)
А еще http://phpfaq[dot]ru/debug
13. Bio man - 25 Сентября, 2011 - 21:25:10 - перейти к сообщению
Champion пишет:
Надо включить показ ошибок, тогда будет видно, почему. display_errors on и error_reporting E_ALL
(Добавление)
А еще http://phpfaq.ru/debug
без изменений. такое поведение подталкивает на мысль что интерфейс это не просто шаблон (скелет) а еще каким то образом управляет классом... ведь логично, что дочтаточно реализации поведения класса и не важно наследует класс интерфейс или нет.... если что то интерфейс Iterator это интерфейс из SPL. не чего не понимаю!
14. caballero - 25 Сентября, 2011 - 22:42:34 - перейти к сообщению
Цитата:
это не просто шаблон (скелет) а еще каким то образом управляет классом


никак он не управляет

Цитата:
если что то интерфейс Iterator это интерфейс из SPL

списки могут содержать элементы разных типов
соответственно итератор должен работать с разными типами
а фиг его знвет какой завтра засунут объект в список
поэтому конструкция которая выполняет итерацию имплементит интерфейс
например вы написали клас который полез в базу и вернул набор данных
вы хотите чтобы по этому набору можно было ходить итераторм - самое простое
ходить через foreach
а значит вы должные реализовать ин соответствующий интерфейс
а компилятор сгенерит код который дергает ваш класа через известные наперед методы

почему нельзя классом обойтись?

потому что разработчик компилятора понятия не иметет какие там создаст классы разработчик сайта.

конечно иногда можно использовать базовый абстрактный клас встроенный в язык и наследоватся от него
но тут два момента:
может не быть общего функционала которые есть смысл выносить в базовый клас
возможно разработчик сайта собирается использовать этот класс в какой то своей иерархии наследования



Вообще вопрос зачем интерфейсы для тех кто пишет не только в пыхе а в яве сишарпе и т.д. даже не стоит. А кто собирается писать только в пыхе с интерфейсами может встретится раз в десять лет
15. MrBeard - 26 Сентября, 2011 - 10:05:35 - перейти к сообщению
я, конечно, понимаю, что из меня программист, как из пробки - пуля)) но я даже на шарпах и яве с интерфейсами сталкивался всего пару раз, и то для написания классов, отвечающих за валидацию сертификатов, к примеру)
А в остальных случаях всегда хватало абстрактного класса, множественное наследование нигде пока не пригодилось

 

Powered by ExBB FM 1.0 RC1