Протокол сравнения в Swift против интерфейса в Java

149

Я прохожу учебник по iOS со страницы разработчиков Apple .

Мне кажется, что protocolи interfaceпочти одинаковый функционал.

  • Есть ли различия между ними?

  • Различное использование в проекте?

обновленный

Да , я прочитал ссылку выше, и я до сих пор не уверен, что различия и использование между protocolи interface. Когда я задаю такой вопрос, я хотел бы увидеть простое объяснение этой темы. Иногда бывает сложно получить все из документации.

булочка
источник
1
Протоколы в Swift и интерфейсы в Java - это одно и то же. Смотрите здесь
Вивек Молкар
69
Я думаю, что подобные вопросы о различиях между языками действительно полезны для понимания особенностей языка. И я не думаю, что они приводят к ненужным взвешенным ответам и не очень легко найти ответ в документации. Поэтому я не думаю, что отрицательные голоса по этому вопросу являются оправданными.
Лий
1
Вот пара критических реальных моментов об интерфейсах Java - stackoverflow.com/a/41143492/294884 - которые будут ключевыми для любого
Fattie
С другой стороны, важно помнить, что весь смысл Swift в том, что он предназначен для «протокольно-ориентированного программирования». Вы делаете все с «расширениями протокола» в Swift повсеместно. Например, здесь есть небольшая проблема со Swift (то есть «о расширениях протокола»), которая иллюстрирует некоторые из проблем.
Толстяк
2
В Swift вместо интерфейсов используется имя протокола, потому что в заголовочных файлах Objective C (бесполезные дубликаты) из C называются интерфейсами
Alex78191

Ответы:

117

По сути, протоколы очень похожи на интерфейсы Java, за исключением:

  • Протоколы Swift также могут указывать свойства, которые должны быть реализованы (например, поля)
  • Протоколы Swift должны иметь дело со значением / ссылкой посредством использования ключевого слова мутации (поскольку протоколы могут быть реализованы структурами и классами)
  • Вы можете комбинировать протоколы в любой момент с ключевым словом protocol <>. Например, объявление параметра функции, который должен соответствовать протоколам A и B, следующим образом:

,

func foo ( var1 : protocol<A, B> ){}

Это сразу очевидные различия для разработчика Java (или, по крайней мере, то, что я заметил до сих пор).

Томас Шар
источник
13
" ключевое слово протокола <> ": это действительно круто! Я думаю, что это то, что называется типом пересечений в сообществе теории систем типов. В Java вы можете иметь такие типы только для параметров типа с несколькими границами. В этой статье предлагается ввести их в Java как тип первого класса с синтаксисом для их обозначения.
Лий
7
Хорошее резюме. Пара более важных функций: протоколы Swift также могут определять требования к связанному типу - например, у типа коллекции есть связанный тип индекса, или для методов сравнения сопоставимого типа требуется параметр того же типа. А в Swift 2.0 расширения протокола могут добавлять фактическую функциональность к типам, которые удовлетворяют требованиям протокола.
Рикстер
2
@rickster Java 8 также может добавить реализацию к интерфейсу, помечая метод default ключевым словом . Смотрите руководство по Oracle .
Василий Бурк
5
Ключевое слово протокола <> теперь удалено в пользу амперсанда. Таким образом, вы можете написать: пусть C: A & B
Пол Робинсон
2
В Swift вместо интерфейсов используется имя протокола, потому что в заголовочных файлах Objective C (бесполезные дубликаты) из C называются интерфейсами
Alex78191
33

Дополняя ответ @Thomas Schar. Магия протокола Swift происходит от расширения.

  • Протоколы Swift могут получить реализации через расширение (Swift
    2). Интерфейс Java 8 может иметь реализации по умолчанию, но это невозможно сделать «задним числом».
  • В Swift вы можете «задним числом» добавить требования к протоколу (и
    его реализации, если необходимо) в любой класс или структуру.
  • Протоколы Swift следуют не общему (т. Е. <..>) шаблону настройки, а схеме typealias (т. Е. Ассоциированным типам). Может быть запутанным в начале, но может избежать
    «слепоты угловых скобок» в некоторых случаях.
  • Swift имеет расширенное сопоставление шаблонов типов, позволяющее очень точно определить, где и как применяются требования и расширения протокола. Это может сбивать с толку, когда приходит с Java, но у него много силы.
  • Быстрый протокол может быть составлен для свойства / параметра (например, празднователь: протокол)

Одна вещь, которая заставила меня почесать голову на пару часов, это то, что не все протоколы могут использоваться в качестве типов свойств. Например, если у вас есть протокол с typealias, вы не можете напрямую использовать его как тип свойства (это имеет смысл, когда вы думаете об этом, но исходя из Java, мы действительно хотим иметь свойство, подобное userDao: IDao).

Джереми Чон
источник
7
Также протоколы Swift могут иметь дополнительные члены, в отличие от интерфейсов Java.
eyeApps LLC
4
Незначительный момент, который всегда возникает в Swift, заключается в том, что (смешно) нет абстрактных функций, поэтому вы просто нажимаете «напечатать, что вы забыли эту!» ... stackoverflow.com/a/24111430/294884
Толстяк
@Fattie. Вы можете использовать ключевое слово «required» для функции, чтобы указать, что требуется реализация подкласса. Так что, на самом деле, больше похоже на незначительное невежество, чем на настоящий момент.
Дирк Бестер
@DirkBester - ура - подожди, ты говоришь с инициализаторами ??
Толстяк
Снова @DirkBester У меня может быть некоторая путаница, но никто не может использовать requiredперед функцией в протоколе, вы просто получаете 'required' may only be used on 'init' declarations...
Толстяк