Menu
Coddy logo textTech

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

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 28 из 91.

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

<?php
interface Printable {
    public function print();
}

class Document implements Printable {
    private $content;
    
    public function __construct($content) {
        $this->content = $content;
    }
    
    public function print() {
        return "Printing: " . $this->content;
    }
}

$doc = new Document("Hello World");
echo $doc->print();

Вывод:

Printing: Hello World

Класс Document реализует Printable, предоставляя собственную версию метода print(). Если вы забудете реализовать обязательный метод, PHP выдаст фатальную ошибку.

Разные классы могут реализовывать один и тот же интерфейс по-своему:

<?php
class Invoice implements Printable {
    private $amount;
    
    public function __construct($amount) {
        $this->amount = $amount;
    }
    
    public function print() {
        return "Invoice Total: $" . $this->amount;
    }
}

$invoice = new Invoice(150);
echo $invoice->print();

Вывод:

Invoice Total: $150

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

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

challenge icon

Задание

Легко

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

Вы создадите три файла, которые работают вместе для обработки различных типов сообщений:

  • Messageable.php — Определите интерфейс Messageable с двумя сигнатурами методов: compose($content) и deliver(). Этот интерфейс устанавливает контракт, которому должны следовать все типы сообщений.
  • Email.php — Создайте класс Email, который реализует Messageable. Подключите файл интерфейса в начале. Класс должен иметь приватное свойство $recipient и приватное свойство $body. Конструктор принимает адрес получателя. Реализуйте compose($content), чтобы сохранить содержимое в $body и вернуть "Email composed". Реализуйте deliver(), чтобы вернуть "Email to [recipient]: [body]".
  • SMS.php — Создайте класс SMS, который также реализует Messageable. Подключите файл интерфейса в начале. Класс должен иметь приватное свойство $phoneNumber и приватное свойство $text. Конструктор принимает номер телефона. Реализуйте compose($content), чтобы сохранить содержимое в $text и вернуть "SMS composed". Реализуйте deliver(), чтобы вернуть "SMS to [phoneNumber]: [text]".

В main.php подключите файлы Email и SMS. Вы получите три входных значения: адрес электронной почты, номер телефона и содержание сообщения. Создайте объект Email с адресом электронной почты и объект SMS с номером телефона. Вызовите compose() с содержанием сообщения для обоих объектов, выводя каждый результат на новой строке. Затем вызовите deliver() для обоих объектов, также выводя каждый результат на новой строке. Порядок должен быть следующим: email compose, SMS compose, email deliver, SMS deliver.

Оба класса выполняют один и тот же контракт Messageable, но каждый обрабатывает составление и доставку сообщений в соответствии со своим назначением — электронные письма показывают адрес получателя, а SMS-сообщения показывают номер телефона.

Шпаргалка

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

<?php
interface Printable {
    public function print();
}

class Document implements Printable {
    private $content;
    
    public function __construct($content) {
        $this->content = $content;
    }
    
    public function print() {
        return "Printing: " . $this->content;
    }
}

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

<?php
class Invoice implements Printable {
    private $amount;
    
    public function __construct($amount) {
        $this->amount = $amount;
    }
    
    public function print() {
        return "Invoice Total: $" . $this->amount;
    }
}

Если класс не реализует все необходимые методы интерфейса, PHP выдаст фатальную ошибку.

Попробуйте сами

<?php
require_once 'Email.php';
require_once 'SMS.php';

// Чтение входных данных
$emailAddress = trim(fgets(STDIN));
$phoneNumber = trim(fgets(STDIN));
$messageContent = trim(fgets(STDIN));

// TODO: Создать объект Email с адресом электронной почты

// TODO: Создать объект SMS с номером телефона

// TODO: Вызвать compose() для обоих объектов и вывести результаты
// Порядок: сначала compose для email, затем compose для SMS

// TODO: Вызвать deliver() для обоих объектов и вывести результаты
// Порядок: сначала deliver для email, затем deliver для SMS
?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование