// содержит инструкции что нужно сделать но не указывает как// все методы в интерфейсе должны быть реализованы в классах// все методы в интерфейсе должны быть публичнымиnamespaceApp;interfaceDebtCollector {publicint$x; // так нельзя, бан. свойства заблокированыpublicconst CONST = 1; // константы разрешены// но их нельзя переопределить в классе (наследование)publicfunctioncollect(float$owedAmount): float;}/*****/classRockyimplementsDebtCollector {publicfunctioncollect(float$owedAmount): float {return$owedAmount * 0.65; }}classCollectionAgencyimplementsDebtCollector { // можно много сразуpublicfunctioncollect(float$owedAmount): float{$guaranteed = $owedAmount * 0.5;returnmt_rand($guaranteed, $owedAmount); // просто рандомный ответ }}classDebtCollectionService{publicfunctioncollectDebt(DebtCollector$collector){ // тут передаем интерфейс//теперь этот класс не заботится о конкретной реализации//интерфейс вызовет нужный метод переданного класса//это же называют полиморфизмом$ownedAmount = mt_rand(100, 1000);$collectedAmount = $collector->collect($owedAmount);echo'Collected $'.$collectedAmount.' out of $'.$owedAmount. PHP_EOL; }}/*****/// где то в коде$service= new \App\DebtCollectionService();echo$service->collectDebt(new \App\CollectionAgency()) . PHP_EOL;echo$service->collectDebt(new \App\Rocky()) . PHP_EOL;//реализация одной и той же идеи в классах может быть разной//интерфейс может принимать любой из них в качестве аргумента
Расширения и наследования интерфейсов
// так можноclassCollectionAgencyimplementsDebtCollector, AnotherInterface {}// и так можноinterfaceDebtCollectorextendsAnotherInterface, AndAnotherInterface {}
Отличия от абстракции
Абстрактный класс можетсодержать реализации методовсвойстваприватные и протектед методырасширяет только один классИнтерфейссодержит только объявление методасодержить только методы и константытолько паблик методыкласс может реализовывать несколько интерфейсов