Задать вопрос
@gerassim

Как изменить тип параметра метода в php при наслодовании?

Допустим у нас есть два интерфейса
interface Message {
    function send();
    function setSender(Sender $sender);
}

interface Sender {
    function send(Message $message);
}


И конкретные реализации
class EmailMessage implements Message {
    private $sender;

    public function setSender(Sender $sender) {
        $this->sender = $sender;
    }
    function send() {
        $this->sender->send($this);
    }
}

class SmtpEmailMessageSender implements Sender{
    private $server;
    private $login;
    private $password;

    public function __construct($server, $login, $password) {
        $this->server = $server;
        $this->login = $login;
        $this->password = $password;
    }

    function send(Message $message) {
         ..... код отправки.....
    }
}


Как реализовать чтобы SmtpEmailSender принимал только EmailMessage для отправки, а не любой Message?
  • Вопрос задан
  • 183 просмотра
Подписаться 2 Оценить Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
elevenelven
@elevenelven
Php Dev @ Amadeus
class SmtpEmailMessageSender implements Sender
{
  private $server;
  private $login;
  private $password;

  public function __construct($server, $login, $password)
  {
    $this->server   = $server;
    $this->login    = $login;
    $this->password = $password;
  }

  function send(Message $message)
  {
    if( !($message instanceof EmailMessage) ){throw new InvalidArgumentException("Instance of 'EmailMessage' expected. Got '".get_class($message)."'");}
    //...
  }
}


Это единственное решение, которое существует для вашего случая.

Другое дело, то что у вас существует некое неявное ограничение. Что вот *вдруг* интерфейс универсален, но вот в этом случае не полностью. Давайте будем принимать на вход не всех кто имплементирует наш интерфейс, а только один класс.
Это неправильно.
Делайте другой интерфейс и пусть ваш EmailMessage имплементирует его. Потому что Принцип разделения интерфейса, довольно разумный подход к написанию кода. А в частности, не может быть универсальной красивой абстракции, что вы и проиллюстрировали. (many client-specific interfaces are better than one general-purpose interface)
Переназовите ваши интерефейсы, так чтобы они соответствовали PSR.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽