interface
Ключевое слово «interface» в PHP используется для определения набора методов, которые класс обязан реализовать. Синтаксис и примеры использования.
Ключевое слово PHP interface
Интерфейс — это контракт: он перечисляет методы, которые класс обязан предоставить, не указывая, как они работают. Любой класс, использующий implements, обязуется определить каждый объявленный метод. Это позволяет программировать исходя из возможности («всё, что можно записать в лог», «всё, что можно сериализовать»), а не исходя из конкретного класса.
Интерфейсы нельзя инстанцировать напрямую — реализации нет. Они существуют для того, чтобы несвязанные классы можно было использовать взаимозаменяемо, если у них одинаковые сигнатуры методов.
На этой странице рассматривается, как объявлять интерфейс, реализовывать один или несколько, совместно использовать константы, расширять интерфейсы и проверять типы во время выполнения с помощью instanceof. Если вы только начинаете работать с объектами в PHP, начните с классов и объектов PHP и что такое ООП.
Синтаксис
Вот базовый синтаксис объявления интерфейса:
interface MyInterface {
public function someMethod();
}Здесь объявляется интерфейс MyInterface с единственным методом someMethod(). Ключевые правила:
- Тела методов опускаются — интерфейс объявляет только сигнатуры, каждая из которых заканчивается точкой с запятой.
- Все методы неявно являются public; можно написать
publicдля ясности, но другие модификаторы доступа не допускаются (private/protectedзапрещены). - Класс принимает интерфейс с помощью ключевого слова
implementsи должен определить каждый метод, иначе PHP выбрасывает фатальную ошибку.
Примеры
Рассмотрим несколько практических примеров использования ключевого слова interface. Первый класс реализует один интерфейс; второй — сразу два (разделённых запятой):
<?php
// Example 1
interface MyInterface {
public function someMethod();
}
class MyClass implements MyInterface {
public function someMethod() {
echo "This is from someMethod." . PHP_EOL;
}
}
$obj = new MyClass();
$obj->someMethod();
// Output: This is from someMethod.
// Example 2
interface MyOtherInterface {
public function someOtherMethod();
}
class MyOtherClass implements MyInterface, MyOtherInterface {
public function someMethod() {
echo "This is from someMethod." . PHP_EOL;
}
public function someOtherMethod() {
echo "This is from someOtherMethod." . PHP_EOL;
}
}
$obj2 = new MyOtherClass();
$obj2->someMethod();
$obj2->someOtherMethod();
// Output:
// This is from someMethod.
// This is from someOtherMethod.В этих примерах мы определяем интерфейсы и используем их в классах PHP, чтобы гарантировать реализацию необходимых методов.
Константы интерфейса
Интерфейс может объявлять константы, которые наследуют все реализующие классы. Они всегда публичны и не могут быть переопределены, что делает их полезными для общих фиксированных значений:
<?php
interface HttpStatus {
const OK = 200;
const NOT_FOUND = 404;
}
class Response implements HttpStatus {
public function describe(): string {
return "Status " . self::OK;
}
}
echo (new Response())->describe() . PHP_EOL;
echo HttpStatus::NOT_FOUND . PHP_EOL;
// Output:
// Status 200
// 404Для констант, которые можно переопределять, используйте константы класса внутри класса.
Расширение интерфейсов
В отличие от классов, интерфейс может extend несколько других интерфейсов. Комбинированный интерфейс требует все методы каждого родителя:
<?php
interface Readable {
public function read(): string;
}
interface Writable {
public function write(string $data): void;
}
// A single interface that demands both capabilities
interface ReadWrite extends Readable, Writable {}
class File implements ReadWrite {
private string $buffer = "";
public function read(): string { return $this->buffer; }
public function write(string $data): void { $this->buffer = $data; }
}
$f = new File();
$f->write("hello");
echo $f->read() . PHP_EOL;
// Output: helloТак PHP симулирует множественное наследование — см. наследование PHP для одиночного наследования классов с помощью extends.
Подсказки типов и instanceof
Поскольку любой реализующий класс удовлетворяет интерфейсу, можно указывать интерфейс как тип в сигнатурах функций и принимать любой подходящий объект. Используйте instanceof для проверки во время выполнения:
<?php
interface Shape {
public function area(): float;
}
class Circle implements Shape {
public function __construct(private float $r) {}
public function area(): float { return 3.14159 * $this->r ** 2; }
}
function printArea(Shape $shape): void {
echo round($shape->area(), 2) . PHP_EOL;
}
$c = new Circle(2);
printArea($c);
var_dump($c instanceof Shape);
// Output:
// 12.57
// bool(true)Интерфейс vs. абстрактный класс
Оба определяют контракт, но решают разные задачи:
- Интерфейс объявляет только сигнатуры методов, и класс может реализовывать многие из них. Используйте его для описания возможности, которую разделяют несвязанные классы.
- Абстрактный класс может предоставлять конкретные методы и свойства наряду с абстрактными, но класс может расширять только один. Используйте его для совместного использования реализации среди связанных классов.
Если нужно совместно использовать код между классами без наследования, обратитесь к трейтам.
Преимущества
Использование ключевого слова interface даёт несколько преимуществ:
- Слабая связанность и гибкость: интерфейсы позволяют заменять реализации без изменения зависимого кода, делая систему более адаптируемой.
- Упрощённое тестирование: они позволяют создавать моки и заглушки, что упрощает юнит-тестирование и отладку.
- Симуляция множественного наследования: поскольку PHP не поддерживает множественное наследование классов, класс может реализовывать несколько интерфейсов и наследовать контракты поведения из нескольких источников.
Заключение
Ключевое слово interface позволяет определить контракт обязательных методов, которые может реализовать любой класс независимо от его места в иерархии классов. В сочетании с подсказками типов и instanceof интерфейсы делают код более гибким, тестируемым и слабосвязанным. Используйте интерфейс, когда хотите описать возможность; используйте абстрактный класс, когда нужно также совместно использовать реализацию.