PHP « php чем отличается интерфейс от абстрактного класса?

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

1 ответов


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


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

В PHP интерфейс это очень ограниченный вариант абстрактного класса:
1. Интерфейс не может содержать реализаций методов.
2. Интерфейс не может содержать описание атрибутов.
3. Интерфейс не может наследовать от классов.
4. Интерфейс может содержать константы.
5. Интерфейс может наследовать от интерфейса.

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

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

Короче, PHP мог бы обогатиться примесями или множественным наследованием.
Выбор был сделан в пользу первого, и в 5.4 появились traits (типажи).


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