Блог веб разработки

Блог веб-разработки статьи | видеообзоры | исходный код

Трейты php

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

Допустим нам нужно реализовать ряд общих методов для всех классов.

Рассмотрим на примере двух классов main и child которым мы с помощью трейта functions определим общий метод profit

<?php

trait functions{ //Объявление трейта
private $percent = 7;

function profit($amount){
return $amount / 100 * $this->percent;
}

//Другие методы
}


class main{

private $amount;

use functions; //Инициализация трейта в классе

}


class child{

    use functions; //Инициализация трейта в классе
}


$main = new main();
$child = new child();
echo $main->profit(1000).'<br/>';
echo $child->profit(100);

Как видите трейты чем то напоминают классы, для которых нельзя создать экземпляр объекта, но их можно включить в другие классы. Для того чтобы определить методы трейта в классе мы используем ключевое слово use и название самого трейта.

Мы также в классе может использовать несколько трейтов перечислая их через запятую, use trait1, trait2 ....;

Но даже не смотря на то что полезность трейтов не вызывает сомнений , они не позволяют изменить тип класса, в который были включены. Поэтому если трейт functions используется сразу в нескольких классах, у вас не будет общего типа, который можно было бы указать в уточнениях сигнатур методов.

К счастью трейты можно использовать вместе с интерфейсами.

interface inter{
    public function profit($amount);
}

trait functions{ //Объявление трейта
private $percent = 7;

function profit($amount){
return $amount / 100 * $this->percent;
}

//Другие методы
}


class main implements inter {

private $amount;

use functions;

}


class child implements inter{

    use functions;
}


$main = new main();
$child = new child();
echo $main->profit(1000).'<br/>';
echo $child->profit(100);

В этом примере мы определили метод трейта через интерфейс.

Также при использовании трейтов может возникнуть,так называемый конфликт имен.

К примеру у нас есть два трейта в которых определены методы с оодиноковыми названиями:

interface inter{
    public function profit($amount);

}

trait functions{ //Объявление трейта
private $percent = 7;

function profit($amount){
return $amount / 100 * $this->percent;
}

//Другие методы
}


trait main {
    



    function profit($amount){
        return $amount / 100 * 10;
    }

}
class child  implements inter{

    use functions,main;
}
$child = new child();
echo $child->profit(100);

Следовательно в такой ситуации у нас возникнет ошибка , так как матод profit есть в этих трейтах. Для разрешения такой проблемы используется ключевое слово insteadof

.

Рассмотрим на конкретном примере:

interface inter{
    public function profit($amount);

}



trait functions{ //Объявление трейта
private $percent = 7;

function profit($amount){
return $amount / 100 * $this->percent;
}

//Другие методы
}


trait main {
 function profit($amount){
        return $amount / 100 * 10;
    }

}
class child  implements inter{

    use functions,main{
        main::profit insteadof  functions;
    }
}
$child = new child();
echo $child->profit(100);

Теперь давайте рассмотрим более подробно что мы здесь понаписали такого:

Во первых как видите ошибки у нас уже нет. Благодаря использованию ключевого слова insteadof.

Во вторых у нас выполнился метод трейта profit трейта main для того чтобы выполнился метод трейта functions нам необходимо записать так:

use functions,main{
        functions::profit insteadof  main;
    }

Как видите к объявлению наших трейтов с помощью ключевого слова use приписывается тело в котором указывается название трейта и через два двоеточия название его метода , а через ключевое слово insteadof название трейта в котором выполнение метода с таким же названием profit будет проигнорировано в пользу трейта main.

Но что если нам нужно использовать эти методы из двух трейтов с одинаковыми названиями в пределах одного класса. Для этого существуют , так называемые псевдонимы

Рассмотрим пример:

interface inter{
    public function profit($amount);

}

trait functions{ //Объявление трейта
private $percent = 7;

function profit($amount){
return $amount / 100 * $this->percent;
}

//Другие методы
}


trait main {




    function profit($amount){
        return $amount / 100 * 10;
    }

}
class child  implements inter{

    use functions,main{
        main::profit insteadof  functions;
        functions::profit as functions_profit;
    }
}
$child = new child();
echo $child->profit(100)."<br/>".$child->functions_profit(100);

Как видите оба метода у нас отлично отрабатывают благодаря использованию псевдонима.

Метод из profit из трейта main мы инициализируем через ключевое слово insteadof ,а метод из functions через псевдоним которому мы через ключевое слово as присвоили имя functions_profit

Ну вот в общем то и все дорогие друзья, надеюсь я смог донести до вас полезную информацию. Желаю удачи!

Оцените статью

Еще статьи

расширения js

datalist HTML

Комбинаторный оператор сравнения в php7

pyautogui python

Модальные окна python

константы php 7

linux systemd

Как установить go

Комментарии

Проверочный код

В данном разделе пока нет комментариев!

История

    ПОДПИСКА

    • Подпишись и получай информацию о выходе новых статей на почту! Просто введите свою почту, нажмите кнопку подписаться. На почту должно будет прийти сообщение с потверждением подписки. Если сообщение не пришло проверьте раздел спам или попробуйте другую почту. Также по всем техническим проблемам вы можете написать в поддержку

    НОВОСТИ

    • Всем привет! Запустил новый сервис для поиска и бесплатного скачивания, прослушивания аудиокниг. Здесь вы можете найти множество литературы и прослушать ее. Вскоре возобновлю написание статей.