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


149

Я переглядаю підручник для iOS зі сторінки розробника Apple .

Мені здається, що protocolі interfaceмайже мають однаковий функціонал.

  • Чи є різниці між ними?

  • різне використання в проекті?

Оновлено

Так , я прочитав посилання вище, і я все ще не впевнений, у чому різниця та використання між protocolта interface. Коли я задаю таке запитання, я хотів би побачити просте пояснення щодо цієї теми. Колись може бути важко дістати все з документації.


1
Протоколи в Swift та інтерфейси на Java - це одне і те ж поняття. Дивіться тут
Vivek Molkar

69
Я думаю, що подібні питання щодо відмінностей між мовами справді корисні для розуміння мовних особливостей. І я не думаю, що вони призводять до зайвих сумнівних відповідей, і не дуже легко знайти відповіді в документації. Тому я не вважаю, що прихильність голосів у цьому питанні виправдана.
Лій

1
Ось кілька критичних реальних моментів щодо інтерфейсів Java - stackoverflow.com/a/41143492/294884 - які були б ключовими для всіх, хто свіжий із Swift, пробуючи Java
Fattie

В іншому напрямку, це чудово пам’ятати, що весь район Свіфта полягає в тому, що він призначений для «протокольного програмування». Ви все робите з "розширеннями протоколів" у Swift всюди. Наприклад, ось тонка проблема про Swift (тобто: "про розширення протоколу"), яка ілюструє деякі проблеми.
Fattie

2
У Swift замість інтерфейсів використовується назва протоколу, оскільки в заголовках файлів Objective C (непотрібні дублікати) з C називаються інтерфейси
Alex78191

Відповіді:


117

По суті протоколи дуже схожі на інтерфейси Java, за винятком:

  • Протоколи Swift також можуть визначати властивості, які необхідно реалізувати (тобто поля)
  • Протоколи Swift повинні мати справу з значенням / посиланням через використання ключового слова, що мутує (оскільки протоколи можуть бути реалізовані структурами та класами)
  • ви можете комбінувати протоколи в будь-якій точці з ключовим словом протокол <>. Наприклад, оголосивши функціональний параметр, який повинен дотримуватися протоколів 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, але це має велику силу.
  • Швидкий протокол може бути складений для властивості / парама (тобто celebrator: протокол)

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


7
Також протоколи Swift можуть мати додаткові члени на відміну від інтерфейсів Java.
ТОВ "eyeApps"

4
Незначний момент, який завжди виникає в Swift, - це те, що (смішно) немає абстрактних функцій, тож ви просто перейдете "друкувати, що ви забули цю!" ... stackoverflow.com/a/24111430/294884
Fattie

@Fattie. Ви можете використовувати "необхідне" ключове слово у функції, щоб вказати, що вона потребує реалізації підкласу. Тож справді, більше схоже на незначне незнання, ніж на фактичну точку.
Дірк Бестер

@DirkBester - ура - чекайте, ви говорите про ініціалізатори ??
Fattie

Знову @DirkBester У мене може виникнути плутанина, але не можна використовувати requiredперед функцією в протоколі, ви просто отримаєте 'required' may only be used on 'init' declarations...
Fattie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.