Являются ли интерфейсы просто «синтаксическим сахаром»?

Я играл в основном с PHP и Python.

Я читал о интерфейсах в OO-программировании и не вижу преимущества в его использовании.

Несколько объектов могут реализовать один и тот же интерфейс, но множественное наследование также не обеспечивает этого?

Почему мне нужно создать интерфейс «без реализации» – в основном «контракт» – если я могу просто проверить, существует ли метод в объекте в Python, который наследуется от нескольких классов?

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

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

В результате Python имеет довольно туманную концепцию «протокола» (реализация, соответствующая определенному шаблону, например, протокол итерации ), который по сути имеет одно и то же, но без других преимуществ проверки времени его компиляции ограниченное.

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

Без интерфейсов (или эквивалентной формулировки, таких как чистые виртуальные функции C ++), выразительность статически типизированного языка будет сильно затруднена. На самом деле существует множество реализаций (Win32 и COM приходят сразу на ум) для существенного воспроизведения большей части функциональных возможностей интерфейсов и виртуальной диспетчеризации в C путем хранения указателей функций в структурах (и, таким образом, повторного внедрения виртуальных функций C ++ и вызова vtable вручную) , В этом случае есть большая разница в выразительности , так как в программе требуется много изменений для выражения тех же понятий.

Интерфейсы – это всего лишь один пример полиморфизма типов и довольно ограниченный. В языках, поддерживающих параметрический полиморфизм (aka generics ), вы можете выполнить гораздо больше. (Например, LINQ C # не будет возможен без общих интерфейсов.) Для гораздо более мощной формы того же типа взгляните на классные классы Haskell.

Прежде всего, постарайтесь не сравнивать и не сравнивать между Python и Java. Это разные языки, с другой семантикой. Сравнение и контраст приведут только к таким путающим вопросам, как это, когда вы пытаетесь сравнить что-то, что Python не использует с тем, что требует Java.

Это очень похоже на сравнение числа 7 и зеленого цвета. Они оба существительные. Кроме того, у вас будет проблема с сравнением этих двух.

Вот итог.

Python не нуждается в интерфейсах.

Java требует их.

Несколько объектов могут реализовать один и тот же интерфейс, но множественное наследование также не обеспечивает этого?

Эти две концепции почти не имеют никакого отношения друг к другу.

Я могу определить большое количество классов, которые имеют общий интерфейс. В Python из-за «утиной печати» мне не нужно быть уверенным, что все они имеют общий суперкласс.

Интерфейс представляет собой объявление «намерения» для непересекающихся классов. Он предоставляет общую спецификацию (которая может быть проверена компилятором), которая не является частью простой иерархии классов. Он позволяет нескольким иерархиям классов реализовывать некоторые общие функции и быть полиморфными по отношению к этим функциям.

В Python вы можете использовать множественное наследование с нашими без интерфейсов. Множественное наследование может включать классы интерфейса или не включать классы интерфейса.

Java даже не имеет множественного наследования. Вместо этого он использует совершенно другой метод под названием «mixins».

Почему мне нужно создать интерфейс «без реализации» – в основном «контракт» – если я могу просто проверить, существует ли метод в объекте в Python, который наследуется от нескольких классов?

Если вы создаете интерфейс в Python, это может быть своего рода формальный контракт. Утверждение, что все подклассы будут абсолютно выполнять то, что требует интерфейс.

Конечно, numbskull совершенно свободен лгать. Они могут наследовать от интерфейса и неправильно реализовывать все. Ничто не мешает плохому поведению от социопатов.

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

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

Поскольку понятия не связаны, на это трудно ответить.

В Java они используют «mixin» вместо множественного наследования. «Интерфейс» позволяет немного смешать дополнительную функциональность. Это одно использование для интерфейса.

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

В большинстве случаев IS и DO изоморфны, поэтому нет различия.

В некоторых случаях, какой объект IS и какой объект имеет значение.

Даже в таких языках, как Python, интерфейс может быть более четким изложением ваших намерений. Если у вас есть ряд реализаций, и они совместно используют набор методов, интерфейс может быть хорошим способом документировать внешнее поведение этих методов, дать концепции имя и сделать концепцию конкретной.

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

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

В статически типизированных языках, таких как Java и .NET, эти интерфейсы становятся важными, потому что методы и их аргументы проверяются во время компиляции.

Теперь для интерфейсов:

Java имеет List в дополнение к массивам. Как правило, массивы предназначены для примитивов (в основном числа), а List – для объектов.

У меня может быть List<String> , который представляет собой список строк. Я знаю, что могу add к нему строки и get строки из него.

Я не знаю, какая это реализация. Это может быть ArrayList (список, поддерживаемый массивом), LinkedList (список поддерживается дублированным списком), CopyOnWriteArrayList ( CopyOnWriteArrayList версия ArrayList ) и т. Д.

Благодаря полиморфизму и интерфейсам мне не нужно знать, какой тип List должен выполнять операции List на нем.

Поскольку вы хотите запрограммировать интерфейс, а не конкретную реализацию ( GoF 1995: 18 )

Потому что иногда вы не хотите предоставлять реализацию.

Интерфейс Java

Класс Java

Да . Что касается PHP, интерфейсы – это просто средство преодоления недостатка множественного наследования. Для IDE существуют незначительные семантические различия, и меньше конфликтов, вызванных интерфейсами, явно помогают программистам-новичкам. Но, как говорилось ранее, это не является строго необходимым для динамических языков. http://c2.com/cgi/wiki?MultipleInheritance

Пожалуйста, прочитайте статью Twisted Framework о силе интерфейсов Zope в python.

Обычно он применяется для замены множественного наследования (C #). Я думаю, что некоторые языки / программисты используют их как способ обеспечения требований к объектной структуре.