абстракция — Почему абстрактные классы необходимы в PHP?

Мы можем использовать простое наследование или интерфейс вместо абстракции.
Почему мы должны использовать абстракцию в PHP? и как мы можем скрыть основные функции, используя абстракцию? Я запутался, используя абстракцию и интерфейс и наследование. Где использовать какой?
Пожалуйста, помогите понять меня.

3

Решение

Я думаю, что важно, во-первых, уточнить терминологию, чтобы более детально ответить на этот вопрос.

  1. наследование
    • Наследование на самом деле широко применяется ко многим принципам и концепциям объектно-ориентированного программирования. Это просто влечет за собой одно, выведенное из другого. Итак, реализуете ли вы интерфейс или расширяете класс, вы все еще используете форму наследования. Они не являются взаимоисключающими понятиями.
  2. интерфейс
    • Попробуйте думать об интерфейсе, как если бы вы были контрактом. Сам контракт — это просто документ, обычно между двумя или более сторонами, в котором изложены правила их отношений. Интерфейсы, особенно в контексте ООП и PHP, не обеспечивают реализацию. Они предоставляют только необходимые публичные методы, которые реализующий класс ДОЛЖЕН воплощать в жизнь. Интерфейсы также не могут быть созданы сами по себе.
  3. абстрактный класс
    • Абстрактный класс похож на интерфейс в том, что он не может быть реализован сам по себе, но не обязательно обеспечивает выполнение контракта для расширяющегося класса. Поскольку это фактический класс, а не просто интерфейс, он также допускает реализацию. Эта реализация может быть предоставлена ​​самим абстрактным классом или оставлена ​​до расширяющего класса, если метод объявлен как abstract в абстрактном классе. Это также позволяет реализовать свойства и частные / защищенные методы, потому что наследование здесь действует как базовый класс, а не просто как требование.

Чтобы ответить на вопрос «почему у нас есть абстрактные классы в PHP«, потому что это полезно. Сначала вы можете рассматривать их как неразрешимые идеи, но на самом деле они могут работать вместе, обеспечивая совместную полезность.

пример

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

interface Device {
public function input(Stream $in);
public function output(): Stream;
}

abstract class DefaultDevice implements Device {
protected $buffer = "";
public function input(Stream $in) {
$this->buffer .= $in->read(1024);
$this->process();
}
abstract protected function process();
}

Так что теперь любой класс, который расширяется DefaultDevice можно либо отменить реализацию input метод или нет. Это также должно реализовать process метод, хотя интерфейс не требует этого. Это означает, что другие классы, реализующие Device Интерфейс может быть обратно совместимым, и это остается деталью реализации.

Дальнейший пример

Отделение реализации от спецификации, как правило, является ключевым атрибутом хорошо написанного программного обеспечения.

Посмотрите на Device Сам интерфейс, как хороший пример. Мы полагаемся на input способ принять Stream тип и output способ вернуть Stream тип. поскольку Streamсам по себе может быть интерфейсом, это означает, что любой тип, реализующий Stream приемлемо Так что я мог создать свой собственный класс и реализовать Stream интерфейс, не нарушая этот код.

class CustomStream implements Stream {
public function read($bytes = 1024) {
/* implementation */
}
public function write($data) {
/* implementation */
}
}

$device->input(new CustomStream); // this will not throw an error
6

Другие решения

abstract Класс используется для предоставления набора членов-данных или методов, которые должны быть доступны для классов, которые наследуются от него, даже если базовый класс не особенно полезен (и никогда не должен создаваться самостоятельно) без унаследованной реализации.

отсюда наследование вступает во владение.

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

2

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

Базовый класс:

class Shape
{
public function draw()
{
}
}

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

Пара производных классов:

class Circle extends Shape
{
public function draw()
{
// the code to draw a circle
}
}

class Rectangle extends Shape
{
public function draw()
{
// the code to draw a rectangle
}
}

Можем ли мы предоставить реализацию метода draw() в базовом классе Shape?

Конечно, нет. Shape является общим, это не означает только «круг» или «прямоугольник» или «треугольник». Нет способа обеспечить разумную реализацию для Shape::draw() потому что мы даже не знаем, какую форму он представляет.

Можно ли предоставить пустую реализацию для Shape::draw()?

Видимо это так. Однако, если подумать, ясно, что это небезопасно. Объекты класса, который расширяется Shape и не обеспечивает собственную реализацию метода draw() не может быть нарисовано.

Потому что класс Shape не может обеспечить достойную реализацию метода shape, он должен как-то сигнализировать об этом производным классам и заставлять их предоставлять реализацию.

То, как это сигнализирует об этой ситуации, является abstract ключевое слово. abstract Метод сообщает читателям класса, что класс не может предоставить реализацию, потому что он слишком универсален и делегирует эту ответственность каждому классу, который его расширяет.

Класс, который имеет abstract метод не полностью определен. Это причина, почему это abstract класс, и он не может быть создан.

1
По вопросам рекламы [email protected]