Реализация интерфейсов
Часть раздела Объектно-ориентированное программирование путешествия по 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 для связывания класса с интерфейсом, затем определите все необходимые методы. Каждый реализующий класс предоставляет свою собственную логику, гарантируя при этом наличие одинаковых сигнатур методов.
Задание
ЛегкоДавайте создадим систему обмена сообщениями, которая демонстрирует, как разные классы могут реализовывать один и тот же интерфейс своими уникальными способами.
Вы создадите три файла, которые работают вместе для обработки различных типов сообщений:
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
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy