Что такое АБСТРАКТНЫЙ КЛАСС и ИНТЕРФЕЙС и когда вы будете использовать их в PHP? - PullRequest
8 голосов
/ 16 сентября 2010

Что такое абстрактный класс и интерфейс в PHP и когда вы будете их использовать? Ответ непрофессионала с примером был бы полезен для моего понимания.

Ответы [ 5 ]

7 голосов
/ 16 сентября 2010

Абстрактные классы и интерфейсы не являются специфичными для PHP; они являются особенностями многих современных объектно-ориентированных языков.

Абстрактный класс - это класс, который имеет одну или несколько не реализованных функций-членов. Вы можете использовать один из них в ситуации, когда вам понадобится набор классов с похожим поведением, отличающихся лишь несколькими методами. Каждый из этих классов будет производным от абстрактного класса и реализует нереализованные методы таким образом, который соответствует их конкретному случаю.

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

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

И абстрактные классы, и интерфейсы допускают полиморфизм; то есть вы можете указать ссылку как на абстрактный тип (который может ссылаться на любой экземпляр класса, производный от него) или на объект, реализующий интерфейс.

4 голосов
/ 16 сентября 2010

Если вы понимаете, почему вы используете их на других языках, те же понятия применимы и к PHP.Интерфейсы класса "подписи" ... они не содержат кода.Абстрактные классы не могут быть созданы, но они могут содержать как реализованные, так и абстрактные (пустые) функции.

Обратите внимание, что класс может расширять только один родительский класс (или абстрактный класс), но он может реализовать столько интерфейсов, сколькоэто необходимо.

Но, учитывая, что PHP не имеет строгой типизации и не имеет концепции проверок времени компиляции, вы можете обычно обходиться без них, в отличие от языков, таких как C ++ или Java.

Ядро PHP требует интерфейсов для некоторых вещей.Например:

class Foo implements Countable
{
  public function count()
  {
    return 5;
  }
}

echo count(new Foo()); // returns 5

Если вы удалите «Implements Countable», PHP не будет вызывать ваш метод count.Есть много других интерфейсов, которые вы можете реализовать, что позволяет всем пользовательским объектам вести себя одинаково.Например, вы можете создать объект, который работает с итерацией * 1013. *

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

function foo(MyInterface $bar)
{
  $bar->someMethod();
}

Если предположить, что someMethod объявлено в MyInterface, тогда вы гарантированно, что вызов $bar->someMethod() существует.(Причина, по которой это не так полезно в PHP, как в других языках, заключается в том, что подсказка типа в сигнатуре функции не будет проверяться до времени выполнения.)

Пустые интерфейсы также могут быть полезны, так какспособы категоризации классов.Скажем, вы хотите сделать что-то для определенного набора объектов.Все они могут реализовать какой-то пустой интерфейс.Тогда ваш код может просто проверить этот интерфейс, даже не зная ничего об объекте.

interface Red {}

class Foo implements Red { }

$foo = new Foo();
if ($foo instanceof Red)
{
  // do something
}

Абстрактные классы полезны, когда у вас есть много кода, который разделяется между подклассами, но незначимый сам по себе.Вы можете объявить базовый класс как абстрактный, реализовать все совместно используемые функции и оставить остальные функции пустыми.Объявив этот базовый класс абстрактным, никто никогда не сможет использовать его сам по себе.

1 голос
/ 19 сентября 2010
1 голос
/ 16 сентября 2010

Руководство по PHP объясняет это просто и предоставляет множество примеров:

0 голосов
/ 16 сентября 2010

Интерфейс определяет набор методов, которые класс должен реализовать. Такой класс реализует интерфейс, предоставляя конкретную реализацию этих методов. Интерфейс не может содержать какую-либо собственную реализацию; это просто набор сигнатур методов. Если я определю интерфейс с именем ILogger, то смогу написать код, который использует методы, определенные в ILogger (возможно, write и writeLine), для передачи сообщений, которые должны быть зарегистрированы. Я могу передать любой класс, который реализует ILogger, и все равно клиентскому коду.

Абстрактный класс похож, но может реализовывать некоторые методы и состояния. Абстрактные классы не могут быть созданы, и любой класс, который их расширяет, должен обеспечивать реализацию каждого метода abstract в родительском классе. Если набор классов разделяет некоторые детали реализации, но отличается от других, то вы можете определить общую реализацию в абстрактном классе, объявить отличающиеся методы абстрактными и позволить дочерним классам заполнить их собственной реализацией. Если бы я хотел единообразный способ сбора системной информации, добавления меток времени и т. Д., Который используется всеми моими регистраторами, я мог бы выбрать создание абстрактного класса LoggerBase, который обрабатывает эти детали, помечая write и writeLine * 1012. * так что любые классы, расширяющие LoggerBase, должны будут просто указать, как записывать в свой конкретный журнал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...