#7.19 php ООП Интерфейсы. Реализация интерфейсов. Наследование интерфейсов. Совместимость сигнатур.

Интерфейсы

Определение интерфейса напоминает определение класса, только вместо class перед именем интерфейса используется ключевое слово interface:

    interface A
    {
    }

Про интерфейсы можно сказать следующее:

  • Интерфейс по сути является абстрактным классом, который содержит только объявления методов без конкретной реализации;
  • Интерфейс не может содержать свойств, но может включать константы;
  • Все методы интерфейса являются публичными (public) или защищёнными (protected) методами;
  • Интерфейсы не используются напрямую. Работа с методами интерфейса возможна после реализации классом.

Реализация интерфейсов классами

Интерфейсы реализуются классами при помощи ключевого слова implements. Например:

<?php
interface camera
{
    public function take_photo();
}

class smartphone implements camera
{
    public function take_photo()
    {
        echo "улыбнитесь<BR>";
    }
}

Все методы, объявленные в интерфейсе, обязательно должны быть определены в реализующем интерфейс классе. Если какой-либо метод не определяется в классе, то такой класс должен быть объявлен абстрактным:

<?php
interface camera
{
    public function take_photo();
}

abstract class smartphone implements camera
{
    //реализация метода take_photo() может отсутствовать в абстрактном классе
}

class xiaomi extends smartphone
{
    public function take_photo()
    {
        //здесь метод take_photo() обязательно должен быть реализован
    }
}

Один и тот же класс может реализовывать несколько интерфейсов:

<?php
interface camera
{
    public function take_photo();
}

interface player
{
    public function play();
}

class smartphone implements camera, player
{
    public function take_photo()
    {
        echo "улыбнитесь<BR>";
    }

    public function play()
    {
        echo "включаем музыку<BR>";
    }
}

Наследование интерфейсов

Механиз наследования интерфейсов такой же, как и для обычных классов. Производный интерфейс наследует базовый и дополняет его собственными методами. Как всегда, для этого используется ключевое слово extends:

<?php
interface camera
{
    public function take_photo();
}

interface camera_and_player extends camera
{
    public function play();
}

class smatphone implements camera_and_player
{
    public function take_photo()
    {
        echo "улыбнитесь<BR>";
    }

    public function play()
    {
        echo "включаем мызыку<BR>";
    }
}

Допускается множественное наследование интерфейсов (в отличие от обычных классов):

<?php
interface photo
{
    public function take_photo();
}

interface video
{
    public function make_video();
}

interface camera extends photo, video
{
}

Совместимость сигнатур

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

  • в дочерний метод могут быть добавлены необязательные параметры;
  • обязательные параметры родительского метода в дочернем могут получать значения по умолчанию;
  • а также должны выполняться условия ковариантности и контравариантности (подробнее см. здесь).

При множественном наследовании, если два предка объявляют методы с одинаковыми именами, то сигнатура метода интерфейса, стоящего в списке предков первым должна быть совместима с сигнатурой метода второго предка.

Правило совместимости сигнатур действует и для классов, реализующих интерфейсы: все методы интерфейса должны быть объявлены в реализующем его классе с совместимыми сигнатурами.

vedro-compota's picture

Наследование интерфейсов

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

_____________
матфак вгу и остальная классика =)