Разница между абстрактным классом и интерфейсом в PHP
Сравнение абстрактного класса и интерфейса в PHP. В чем разница между абстрактным классом и интерфейсом в PHP? Это один из самых распространненых вопросов на собеседованиях.
В этом уроке вы узнаете некоторые важные различия между абстрактным классом и интерфейсом.
Интерфейс в PHP
Интерфейс — это соглашение, контракт или договор. Когда класс реализует интерфейс, это означает, что он содержит публичные методы интерфейса и их реализации.
Когда мы создаем интерфейс в приложении, мы определяем контракт на то, что наш класс может делать, ничего не говоря о том, как этот класс будет это делать.
// Defined cacheInterface interface cacheInterface < public function get($key); public function set($key,$value); >/* * A Memcache class implements cacheInterface */ class Memcache implements cacheInterface < public function get($key)< // method body >public function set($key,$value) < // method body >>
В приведенном выше примере создается cacheInterface , содержащий публичные методы get() и set() . Любой класс, который реализует этот интерфейс, должен определить методы get() и set() .
В этом примере класс Memcache реализует cacheInterface . Это означает, что он придерживается контракта и определяет тело методов get() и set() . Аналогично, если какой-либо другой класс кэширования реализует этот интерфейс, он определит методы get() и set() .
Абстрактный класс в PHP
Абстрактный класс используется для определения базового каркаса или проекта дочерних классов. Класс, который расширяет абстрактный класс, должен определять некоторые или все его абстрактные методы.
Экземпляры абстрактных классов не могут быть созданы напрямую.
abstract class car < abstract public function modelType(); public function wheelCount() < echo "I have four wheels"; >> class HondaCity extends car < public function modelType()< echo "HondaCity"; >> $data = new HondaCity; $data->modelType(); $data->wheelCount();
Сравнение абстрактного класса и интерфейса в PHP
| Интерфейс | Абстрактный класс |
|---|---|
| Поддерживаем множественное наследование | Не поддерживаем множественное наследование |
| Не содержит data members | Может содержать data members |
| Не содержит конструктор | Может содержать конструктор |
| Содержит только объявление методов (сигнатуры методов) | Может содержать как сигнатуры методов так и их реализации |
| Не может иметь модификаторов доступа — все методы по умолчанию публичные | Может иметь модификаторы доступа |
| Методы не могут быть статическими | Только методы, содержащие реализацию, могут быть объявлены статическими |
1. Абстрактный класс действует как образец для классов, которые его наследуют. Дочерний класс, который наследует абстрактный класс, должен реализовывать методы, объявленые абстрактными в родительском классе. Абстрактный класс создается только для как элемент иерархии наследования. Это означает, что вы не можете создать объект абстрактного класса.
Интерфейс — это контракт. Он содержит только сигнатуры методов (без тела метода). Класс, который реализует интерфейс, должен реализовывать эти методы.
2. Класс может расширять только один абстрактный класс, тогда как класс может реализовывать несколько интерфейсов.
interface A <> interface B <> interface C <> //A class can implements multiple interfaces class Base implements A, B, C <>
3. В абстрактном классе мы можем определить переменные экземпляра и конкретные (неабстрактные) методы.
Но в интерфейсе все методы абстрактны. Мы не можем определить переменные экземпляра, но мы можем определить константы в интерфейсе.
4. Абстрактный класс хорош, когда есть некоторые общие черты, которые должны быть общими для всех объектов.
Используйте интерфейс, когда все функции должны быть реализованы по-разному для разных объектов. Все методы cacheInterface будут реализованы по-разному для всех классов.
Например — класс Memcache определяет тело метода get() и set() , но их реализация будет отличается от класса Redis.
PHP: Разница между Трейтом, Интерфейсом и Абстрактным классом
Эти три структуры могут сбить с толку новичков в PHP или опытных разработчиков, поэтому давайте рассмотрим, что делает каждая из них и когда их лучше всего использовать.
Если вы постоянно работаете с PHP, то скорее всего сталкивались с Интерфейсом, Трейтом или Абстрактным классом. На первый взгляд может показаться, что между ними есть некоторое сходство, и трудно определить их различия и варианты использования. К концу этой статьи вы легко сможете сказать, что отличает их друг от друга и когда предпочтительнее использовать один или другой.
TL;DR;
- Абстрактный класс может содержать сигнатуры методов, а также общие методы, но не может быть создан сам по себе. Хорошо подходит для создания общего родителя для совместного использования между классами.
- Трейт — группа свойств и методов для повторного использования кода, и в один класс можно добавить несколько. Хорошо подходит для организации кода и уменьшения повторений.
- Интерфейс — набор сигнатур методов для обеспечения конкретной реализации в классе, к которому они добавляются. Хорошо подходит для добавления структуры и стандартизации.
Хотите узнать больше о каждом из них? Читайте дальше!
Абстрактный класс
Абстрактный класс по структуре похож на обычный класс, но содержит абстрактные методы. В отличие от обычного класса не может быть создан сам по себе. Является хорошей отправной точкой для классов, которые, скорее всего, будут иметь общего родителя.
Допустим у нас были классы Cat , Dog и Hamster . У них могут быть общие методы и функциональные возможности, поэтому можно создать родительский абстрактный класс как для добавления общих методов, так и для обеспечения необходимой реализации в дочерних классах.
Родительский абстрактный класс для них может выглядеть так:
abstract class Pet
abstract protected function greet();
public function hasFur()
return true;
>
>
У нас есть абстрактный метод greet() , который заставляет любой класс расширяющий Pet реализовать этот метод. Затем у нас есть публичный метод hasFur() , который будет доступен для любого объекта, созданного из класса, расширяющего этот абстрактный класс.
Итак, теперь мы можем создать класс для определённого вида домашних животных:
class Cat extends Pet
public function greet()
return 'Meow!';
>
>
$cat = new Cat();
$cat->greet(); // Meow!
$cat->hasFur(); // true
Выводы об абстрактных классах:
- Не могут быть созданы сами по себе
- Абстрактные методы просто объявляют сигнатуру (без функциональности)
- Используются дочерними классами с расширениями
- Действует как своего рода частично построенный класс
Трейт
Трейты — способ повторного использования кода в нескольких (иногда совершенно несвязанных между собой) классах. В отличие от абстрактных классов, в одном классе можно использовать несколько трейтов с помощью оператора use .
Трейты регулярно используют для группировки нескольких связанных между собой методов и свойств, добавляя эту функциональность к классам, в которых они используются.
Например, у нас может быть два трейта HasLegs и HasFins :
trait HasLegs
public function walk()
$steps = 0;
while (true)
$steps++;
>
>
>
trait HasFins
public function swim()
$laps = 0;
while (true)
$laps++;
>
>
>
Мы продолжаем работать с животными из предыдущих примеров, так что давайте представим, что у нас есть объект Cat , у которого явно есть ноги и он может ходить. Мы можем использовать трейт HasLegs , чтобы дать нашему классу Cat метод walk() , который можно использовать:
class Cat
use HasLegs;
>
$cat = new Cat();
$cat->walk();
Или, что у нас есть объект Duck , у которого есть ноги и плавники? Мы можем использовать оба трейта и дать нашему классу методы walk() и swim() :
class Duck
use HasLegs, HasFins;
>
$duck = new Duck();
$duck->walk();
//или
$duck->swim();
Выводы о трейтах:
- Идеально подходит для повторного использования кода
- Реализуется в теле класса с use
- В одном классе можно использовать несколько
- Может иметь как свойства так и методы
Интерфейс
Интерфейсы — способ принудительного применения определённых реализаций в классах, которые их используют. Интерфейсы могут содержать только сигнатуры методов, в них вообще нет никакой функциональности. В основном они предназначены для обеспечения структуры и служат чертежами для построения классов.
Возьмём этот пример интерфейса:
interface Bug
public function legs();
public function eyes();
>
Опять, никакой реализации методов legs() и eyes() , только сигнатура, которую они требуют в классах включающих этот интерфейс. Итак, если мы создаём классы, реализующие наш интерфейс Bug , эти метода должны быть доступны в каждом из них.
class Spider implements Bug
public function legs()
return 8;
>
public function eyes()
return 8;
>
>
class Beetle implements Bug
public function legs()
return 6;
>
public function eyes()
return 2;
>
>
Итак, теперь у нас есть два класса, каждый из которых реализует интерфейс Bug , каждый из них должен включать методы legs() и eyes() , а также собственную (обычно уникальную) реализацию.
Выводы об интерфейсах:
- Действуют как чертежи для классов
- Используются в объявлении класса с реализациями
- Можно использовать несколько интерфейсов в одном классе
- Содержит только сигнатуры методов (без свойств)
Надеюсь теперь вы лучше понимаете различия и сходства между абстрактными классами, трейтами и интерфейсами. Каждый из них мощный и при различных сочетаниях может добавить много мощности и структуры вашим PHP-приложениям.
PHP: Используем Интерфейсы для улучшения кода
Важно убедится, что ваш код легко читается, поддерживается, расширяется и тестируется. Один из способов улучшить эти факторы — использовать интерфейсы.
www.dev-notes.ru
PHP: Интерфейсы vs Абстрактные классы
Я решил написать статью, объясняющую различия между абстрактными классами и интерфейсами в PHP и дать краткий обзор, когда нужно использовать каждый из них.
Понимание и применение Интерфейсов и Абстрактных классов
Эта статья появилась на основе многочисленных вопросов о том, что такое интерфейсы и абстрактные классы в PHP, и какое между ними отличие. В этой статье, я, на основе простых примеров постарался описать идеи использования интерфейсов и абстрактных классов в PHP. А так же, описал, в каких случаях следует использовать абстрактный класс, а в каких — интерфейс.
Интерфейс
Мы знаем, что интерфейс определяет ключевую структуру классов, шаблоны логики, которую необходимо будет реализовать всем имплементирующим этот интерфейс классам. Так же, известно, что все методы интерфейса абстракты (не имеют реализации, какой-то логики). Интерфейс определяет только шаблоны методов и их сигнатуру. Все методы интерфейсов должны быть публичными.
Вот пример простого интерфейса:
interface Logger
В интерфейсе не определяется тело метода, просто имя метода и входные параметры. Если не использовать интерфейсы, то какая проблема может наступить? И почему, использование интерфейсов — это так важно? Ниже я постараюсь ответить на эти вопросы, на примере такого кода:
class DatabaseLogger < public function execute($message) < // сохраняем сообщение $message лога в базу данных >> class FileLogger < public function execute($message) < // сохраняем сообщение $message лога в файл >> class UsersController < protected $logger; public function __construct(FileLogger $logger) < $this->logger = $logger; > public function show() < $user = \Auth::user(); $this->logger->execute("Пользователь id> выполнил какое-то действие."); > > $controller = new UsersController(new FileLogger()); $controller->show();
В описанном примере я не использовал интерфейс. Я пишу сообщения в лог, используя класс FileLogger . Но, сейчас, если мне вдруг придётся поменять логгер, чтобы запись производилась в базу данных, то придётся вместо записанного класса FileLogger написать DatabaseLogger , чтобы было так:
// так было раннее // public function __construct(FileLogger $logger) // так стало public function __construct(DatabaseLogger $logger) // класс UsersController
В большом проекте, если вы имеете множество классов, в которых был задействован логгер, то такие правки придётся вручную внести в каждом из этих файлов. Но, когда мы используем интерфейс, то эта проблема решается, и нам больше не требуется менять каждый захардкоженый подобным методом класс.
Сейчас, давайте посмотрим на код ниже, в котором реализуем работу с интерфейсом:
interface Logger < public function execute(); >class DatabaseLogger implements Logger < public function execute($message) < // сохраняем сообщение $message лога в базу данных >> class FileLogger implements Logger < public function execute($message) < // сохраняем сообщение $message лога в файл >> class UsersController < protected $logger; public function __construct(Logger $logger) < $this->logger = $logger; > public function show() < $user = \Auth::user(); $this->logger->execute("Пользователь id> выполнил какое-то действие."); > > $controller = new UsersController(new DatabaseLogger()); $controller->show();
И в этом случае, если я изменю использование логгера с FileLogger на DatabaseLogger , мне больше не придётся изменять метод контроллера напрямую. В конструктор я заинжектил интерфейс, вместо жестко указанного конкретного класса реализацию, таких как DatabaseLogger или FileLogger .
Если вы имеете несколько классов и меняете одну его реализацию на другую, при использовании интерфейсов вы добьётесь эффекта подмены реализаций без единой правки сигнатур методов.
В этом примере я использовал логгер DatabaseLogger , и теперь, чтобы просто переключиться на файлов лог, то достаточно написать:
$controller = new UsersController(new FileLogger()); $controller->show();
И я получил результаты без изменения кода в других классах, где используется этот логгер. А всё это потому, что мы программируем на основе интерфейса, а не конкретного класса. И интерфейс в этом случае очень упрощает процесс подмены разных реализаций.
Абстрактный класс
Абстрактный класс — это класс, который имеет только частично реализованную логику. Если класс содержит как минимум один абстрактный метод, который не имеет готовой реализации (содержит просто имя и принимаемые параметры) и метод обозначен как абстрактный abstract , то такой класс помечается как абстрактный соответственно. То есть, абстрактный класс — это что-то среднее между интерфейсом и обычным классом. Отличие абстрактного класса от интерфейса заключается в том, что он может содержать логику в методах. А общее — то, что, как и интерфейс, он описывает шаблоны методов которые необходимо реализовать.
Абстрактный метод — это простая функция, которая указывает программисту на необходимость реализации этого метода в дочернем классе с соответствующей сигнатурой. Вот пример:
abstract class AbstractExample < // метод без логики, флаг abstract обязует программиста определить логику в дочерних классах (классах-наследниках) abstract protected function getValue(); // определённая логика, которая считается общей, независимо от потенциальной реализации public function printOut() < print $this->getValue() . PHP_EOL; > >
Но, теперь вопрос на миллион, в каких случаях этот абстрактный метод должен быть определён? Ниже я постараюсь ответить на этот вопрос и объяснить:
class Tea < public function addTea() < var_dump('Добавить щепотку чая.'); return $this; >protected function addHotWater() < var_dump('Добавить горячей воды.'); return $this; >protected function addSugar() < var_dump('Добавить ложку сахара.'); return $this; >protected function addMilk() < var_dump('Добавить молоко.'); return $this; >public function make() < return $this ->addHotWater() ->addSugar() ->addTea() ->addMilk(); > > $tea = new Tea(); $tea->make(); // завариваем чай
Дальше, реализуем похожий класс для кофе:
class Coffee < public function addCoffee() < var_dump('Добавить ложку кофе.'); return $this; >protected function addHotWater() < var_dump('Добавить горячей воды.'); return $this; >protected function addSugar() < var_dump('Добавить сахара.'); return $this; >protected function addMilk() < var_dump('Добавить молока.'); return $this; >public function make() < return $this ->addHotWater() ->addSugar() ->addCoffee() ->addMilk(); > > $tea = new Coffee(); $tea->make(); // сделали кофе
В описанных двух классах 3 метода addHotWater() , addSugar() и addMilk() имеют одну и ту же логику, потому, нам нужно избавиться от дублируемого кода. И, это как раз и является ответом на вопрос, когда использовать абстрактный класс: в случае, когда существует определённая общая логика для всех абстракций классов. И поступить можно таким путём:
abstract class Template < public function make() < return $this ->addHotWater() ->addSugar() ->addPrimaryToppings() ->addMilk(); > protected function addHotWater() < var_dump('Добавить горячей воды.'); return $this; >protected function addSugar() < var_dump('Добавить сахара.'); return $this; >protected function addMilk() < var_dump('Добавить молока.'); return $this; >protected abstract function addPrimaryToppings(); > class Tea extends Template < // пишем логику для абстрактного метода public function addPrimaryToppings() < var_dump('Добавить щепотку чая.'); return $this; >> class Coffee extends Template < // пишем логику для абстрактного метода public function addPrimaryToppings() < var_dump('Добавить ложку кофе.'); return $this; >> // сделать чай $tea = new Tea(); $tea->make(); // сделать кофе $coffee = new Coffee(); $coffee->make();
Я сделал абстрактный класс с именем Template . В нём я определил методы с реализацией: addHotWater() , addSugar() и addMilk() , а так же, добавил абстрактный метод addPrimaryToppings() , который, в каждой из реализаций будет отличаться и содержать собственную логику.
Сейчас, классом Tea унаследоваться от класса Template , он сходу получит 3 готовых метода от абстрактного класса, и один абстрактный, в котором обязательно нужно написать свою логику. С классом Coffee дела обстоят таким же образом.

В серці. Назавжди.
Вчора у мене помер однокласник. А сьогодні бабуся. І хто б міг уявити, що цей рік принесе війну, смерть товариша, та смерть члена сім’ї? Це боляче. Проте це добре нагадування про те, як швидко тече час. І як його ціна збільшується кожної марно витраченої секунди. І я не скажу щось
20 мая 2022 г. 1 min read

Ось такий він, руський мир
«Руський мир» — звучить дуже сильно та виправдовуюче. Гарна обгортка виправдання слабкості, аморальності та нікчемності своїх дійсних намірів. Руський мир, який дуже солодко звучить для всіх, хто хоче закрити очі на факт повномасштабної війни. Дуже добре виправдання вбивства для купки звірів. Втім, це ж росія, в якій все виглядає логічно
16 апр. 2022 г. 3 min read

Перехват запросов и ответов JavaScript Fetch API
Перехватчики — это блоки кода, которые вы можете использовать для предварительной или последующей обработки HTTP-вызовов, помогая в обработке глобальных ошибок, аутентификации, логирования, изменения тела запроса и многом другом. В этой статье вы узнаете, как перехватывать вызовы JavaScript Fetch API. Есть два типа событий, для которых вы можете захотеть перехватить HTTP-вызовы:
PHP: Интерфейсы vs Абстрактные классы
Недавно я опубликовал статью об улучшении PHP кода с помощью интерфейсов. Она охватывает основы того что такое интерфейс, что он может делать. И как вы можете использовать его сделав свой PHP код более расширяемым и поддерживаемым. Один из вопросов, заданных в комментариях к статье был от разработчиков, которые хотели знать «когда я должен использовать интерфейс вместо абстрактного класса?». Я подумал и решил написать статью, что бы объяснить различия между абстрактными классами и интерфейсами в PHP и дать краткий обзор того, когда вы должны использовать каждый из них.
Что такое Интерфейсы
В общих чертах, Интерфейс должен описывать, как будет построен класс реализующий его, это похоже на план, описывающий публичные методы и константы, которые должны быть реализованы.
Интерфейсы должны:
- Использоваться для определения публичных методов класса.
- Использоваться для определения констант класса.
Интерфейсы не должны:
- Использоваться сами по себе.
- Использоваться для определения приватных или защищённых методов класса.
- Использоваться для определения свойств класса.
Интерфейсы используются для определения публичных методов, которые должен включать класс. Важно помнить, что интерфейс всегда предназначен для реализации классом, поэтому в нём вы определяете только сигнатуру метода, например:
interface HomeInterface
const MATERIAL = 'Brick';
public function openDoor(): void;
public function getRooms(): array;
public function hasGarden(): bool;
>
а не как в следующем примере:
interface HomeInterface
public string $material = 'Brick';
public function openDoor(): void
// Открываем дверь.
>
public function getRooms(): array
// Даём информацию о комнатах.
>
public function hasGarden(): bool
// Задаём есть ли у дома сад.
>
>
Согласно php.net, интерфейсы служат нескольким целям:
- Позволить разработчикам создавать объекты разных классов, которые могут использоваться взаимозаменяемо, поскольку они реализуют один и тот же интерфейс или интерфейсы. Типичный пример — несколько служб доступа к базе данных, несколько платёжных шлюзов или разные стратегии кэширования. Различные реализации могут быть заменены, не требуя каких-либо изменений в коде, который их использует.
- Позволить функции или методу принимать и оперировать параметром, который соответствует интерфейсу, не заботясь о том, что ещё может делать объект или как он реализован. Эти интерфейсы часто называют Iterable , Cacheable , Renderable и т.д., чтобы описать поведение.
Используя наш выше описанный интерфейс и придерживаясь аналогии с домом, мы могли бы создавать различные классы реализующие HomeInterface такие, как House , Flat или Caravan . Используя интерфейс, мы можем быть уверены, что наш класс содержит три необходимых метода и все используют правильную сигнатуру метода. Например, у нас может быть класс House , который выглядит так:
class House implements HomeInterface
public function openDoor(): void
// Открываем дверь здесь.
>
public function getRooms(): array
// Даём информацию о комнатах.
>
public function hasGarden(): bool
// Задаём есть ли у дома сад.
>
>
Что такое Абстрактные классы
Абстрактные классы PHP очень похожи на интерфейсы PHP; они не предназначены быть классами сами по себе и представляют базовые методы без реализации.
Возьмём пример с домами, приведённый выше, если интерфейс является вашим планом, то абстрактный класс — это ваша модель выставочного зала. Он работает, и это отличный пример дома, но вам всё равно нужно его обставить и украсить, чтобы сделать его своим.
Абстрактный класс может:
- Использоваться для определения сигнатур методов класса с использованием abstract методов (аналогично интерфейсам).
- Использоваться для определения методов.
- Использоваться для определения констант класса.
- Использоваться для определения свойств класса.
- Расширятся дочерним классом.
Абстрактный класс не может:
- Использоваться самостоятельно
Что бы понять, что это означает, рассмотрим пример абстрактного класса:
abstract class House
const MATERIAL = 'Brick';
abstract public function openDoor(): void;
public function getRooms(): array
return [
'Bedroom',
'Bathroom',
'Living Room',
'Kitchen',
];
>
public function hasGarden(): bool
return true;
>
>
Наш класс House объявлен abstract — это означает, что мы не можем использовать его напрямую. Для использования нужно его унаследовать. Например, давайте создадим класс MyHouse , который расширяет абстрактный класс House :
class MyHouse extends House
public function openDoor(): void
// Открываем дверь.
>
public function getRooms(): array
return [
'Bedroom One',
'Bedroom Two',
'Bathroom',
'Living Room',
'Kitchen',
];
>
>
// Это не будет работать:
$house = new House();
// Это будет работать:
$house = new MyHouse();
Вы могли заметить, что в классе House мы объявили абстрактный публичный метод openDoor() . Это позволяет нам определить сигнатуру метода, которую дочерний класс должен включать, аналогично тому, как мы делали бы с интерфейсом. Это действительно удобно, если вы хотите поделиться функциональностью с дочерними классами, но при этом обеспечить возможность собственной реализации некоторых методов.
В этом случае дочерний класс мог бы переопределить методы getRooms() и hasGarden() , но не должен был бы их включать. Что продемонстрировать это, мы переопределили метод getRooms() показав, как мы можем изменить его поведение в дочернем классе.
Как решить, что использовать
Это зависит от вашей цели. Сохранив аналогию с домом, если вы создаёте чертежи, которые в дальнейшем можно использовать для проектирования домов разных типов, вам нужен интерфейс.
Если вы построили дом и вам нужно создать копии с улучшениями, то вам нужен абстрактный класс.
Приведу несколько примеров:
Когда использовать Интерфейс
Чтобы помочь понять, когда нужно использовать интерфейс, давайте рассмотрим пример. Допустим, у нас ест класс ConstructionCompany включающий метод buildHome() , который выглядит следующим образом:
class ConstructionCompany
public function buildHome($home)
// Строим дом.
return $home;
>
>
Теперь предположим, что у нас есть 3 разных класса, которые мо хотим создать и передать методу buildHome() :
- class MyHouse implements HomeInterface extends House
- class MyCaravan implements HomeInterface
- class MyFlat implements HomeInterface
Как мы видим, класс MyHouse расширяет абстрактный класс House ; и это имеет смысл к концептуальной точки зрения, потому что дом есть дом. Однако класс MyCaravan или MyFlat не имеет смысла расширять от абстрактного класса, потому что ни один из них не является домом.
Итак, поскольку наша строительная компания может строить дома, фургоны и квартиры, это правило исключает указание параметра $home в методе buildHome() как экземпляра House .
Однако это было бы идеальным местом для указания типа нашему методу, что бы разрешить принимать только классы реализующие HomeInterface . В качестве примера мы могли бы обновить метод следующим образом:
class ConstructionCompany
public function buildHome(HomeInterface $home)
// Строим дом.
return $home;
>
>
В результате мы можем быть уверенными, передавая значение дом, фургон или квартира, что наш класс ConstructionCompany получит необходимую информацию. Переданный объект home всегда будет содержать необходимые нам методы.
Вы могли подумать: Почему бы нам просто не создать абстрактный класс Home вместо интерфейса? . Однако важно помнить, что PHP поддерживает только одиночное наследование и что класс не может расширять более одного родителя. Таким образом, это будет довольно сложно, если вы захотите расширить один из своих классов в будущем.
Когда использовать Абстрактный класс
Возьмём сценарий аналогичный приведённому выше. Давайте представим, что у нас есть HouseConstructionCompany , похожая на нашу ConstructionCompany . Но в этом примере предположим, что компания HouseConstructionCompany строит только дома и ничего больше.
Поскольку мы знаем, что нам нужно уметь строить только дома, мы можем указать, что бы наш метод принимал только те классы, которые являются расширением абстрактного класса Home . Это может быть действительно полезно, так как мы всегда будем уверены, что передаём типы только тех домов которые строительная компания строит. Например:
class HouseConstructionCompany
public function buildHouse(House $house)
// Build the house here.
return $house;
>
>
Вывод
Надеюсь эта статья даст представление о различиях между интерфейсами и абстрактными классами в PHP. А так же различных сценариев того, когда следует их использовать.
PHP: Разница между Трейтом, Интерфейсом и Абстрактным классом
Эти три структуры могут сбить с толку новичков в PHP и опытных разработчиков, поэтому давайте рассмотрим, что делает каждая из них и когда их лучше использовать
www.dev-notes.ru
PHP: Используем Интерфейсы для улучшения кода
Важно убедится, что ваш код легко читается, поддерживается, расширяется и тестируется. Один из способов улучшить эти факторы — использовать интерфейсы.
