Рейтинг@Mail.ru
 
Интерфейсы

Красивое название. И вроде бы интуитивно понятное. Но тут опять корется некоторый подвох.
Дело в том, что интерфейс - слово нарицательное, и часто обозначает "устройство для управления". Так вот, ничего общего с управлением интерфейс в ООП не имеет. Есть более точное (жаргонное) определение этого явления - контракт. Но ближе к телу, как говорится.

Сначала, как водится, пример из жизни. Вот ситуация. Допустим опытный и очень занятой программист всю ночь играл в кваку работал над проектом. И его подающий надежды сын ему помогал. Как только забрезжил рассвет, оба обессиленные, но с чуством исполненного долга, свалились спать. А утром жена, собираясь на работу, оставляет такую записку:
Оболтусы, как проснетесь:
1. Убрать носки из под дивана
2. Съесть котлеты на плите
3. Помыть за собой посуду
Ей не важно как они это будет делать. Ей важно, что бы все было реализовано обоими и в полной мере.
Вот оболтусы - это классы. А жена - интерфейс. Она определяет то, что обязаны выполнить её чада. Заметьте - она не дает подробных инструкций, ей не важно, кто как будет есть котлеты. Гретые или холодные. Она просто раздает абстрактные задания, невыполнение которых повлечет неминуемый варнинг.

Интерфейс является своего рода соглашением между разными классами - какие методы должны присутствовать обязательно. Отсюда и жаргонное - контракт.
Служат они исключительно для того, что бы вконец не заблудиться в лабиринтах наследований и не наделать разноброда. Дело в том, что в PHP нельзя сделать так, чтобы класс был наследником двух других одновременно. Это в жизни можно получить наследство от бабушки и любимой тети. Тут нет.

Вот в жизни как. Допустим мы строим завод по производству автомобилей. Один цех делает кузова, другой моторы. А третий сборочный. В PHP так нельзя. Но можно сделать два цеха, которые будут делать разные машины. Так вот, что бы не получилось так, что производится один кузов без мотора, есть жесткие предписания - интерфейсы.

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

В кодовом представлении пример с оболтусами будет выглядеть так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php

    
interface Wife_Interface  
    
{  
        function 
cleanSocks();  
        function 
areCutlets(); 
        function 
washWare();          
    } 
     
     
    class 
Husband implements Wife_Interface  
    
{          

        public function 
cleanSocks()  
        {  
            return 
'Задвинуть подальше'
        } 
          
        public function 
areCutlets()  
        {  
            return 
'Схавать стоя, запивая пивом'
        }     
      
        public function 
washWare()  
        {  
            return 
'Свалить на сына (морской закон)'
        }  
      
        public function 
goInternet()  
        {  
            return 
'Зайти на любимый форум'
        }          
             
    }     
     
     
    class 
Son implements Wife_Interface  
    
{          

        public function 
cleanSocks()  
        {  
            return 
'Отнести в карзину для белья'
        } 
          
        public function 
areCutlets()  
        {  
            return 
'Разогреть и намазать вареньем'
        }     
      
        public function 
washWare()  
        {  
            return 
'Ополоснуть в холодной воде и спрятать в шкаф подальше'
        }  
      
        public function 
goSchool()  
        {  
            return 
'Поплестись в школу'
        }  
    }   

То есть методы в классах реализованы по разному. Кроме того, могут присутствовать и другие методы. Но эти должны быть обязательно.

Но что получилось. В результате отец не мыл посуду, а скажет, что мыл. Наврет.
По этому возможен вариант с пустым методом, но присутствовать он должен однозначно. Вот так:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

    
class Husband implements Wife_Interface   
    
{           

        public function 
cleanSocks()   
        {   
            return 
'Задвинуть подальше';  
        }  
           
        public function 
areCutlets()   
        {   
            return 
'Схавать стоя, запивая пивом';  
        }      
       
        public function 
washWare(); 
       
        public function 
goInternet()   
        {   
            return 
'Зайти на любимый форум';  
        }           
              
    }  


В интерфейсе не нужно указывать типы методов, достаточно просто обозначить их присутствие. Привязывается класс к интерфейсу ключевым словом implements

Класс можно привязать к нескольким интерфейсам, перечислив их через запятую. Допустим кроме жены с вами живет еще и любимая теща. И тоже пишет строгие записки.

Интерфейс, это своего рода активный комментарий. Пользы от интерфейсов в готовом к бою коде, что от седла корове. Вроде бы и не вредит особо, но удои точно не повышает.

Это просто заплатка на не совсем красиво реализованный механизм наследований в PHP