Интерфейсы - это просто "синтаксический сахар"? - PullRequest
9 голосов
/ 28 июня 2010

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

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

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

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

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

Ответы [ 9 ]

13 голосов
/ 28 июня 2010

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

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

Вот нижняя строка.

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

Java требует их.

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

Эти два понятия почти не имеют ничего общего друг с другом.

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

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

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

У Java даже нет множественного наследования.Вместо этого он использует совершенно другую технику, называемую «mixins».

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

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

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

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

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

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

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

Другое использование интерфейса для отделения «есть» от «делает».Иерархия классов определяет, что такое объект.Иерархия интерфейса определяет, что класс ДОЛЖЕН.

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

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

11 голосов
/ 28 июня 2010

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

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

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

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

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

5 голосов
/ 28 июня 2010

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

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

4 голосов
/ 28 июня 2010

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

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

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

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

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

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

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

3 голосов
/ 28 июня 2010

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

1 голос
/ 30 июня 2010

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

1 голос
/ 28 июня 2010

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

1 голос
/ 28 июня 2010

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

Интерфейс Java

Java класс

0 голосов
/ 28 июня 2010

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

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