Porównaj protokół w Swift i interfejs w Javie

149

Przechodzę przez samouczek iOS ze strony programisty Apple .

Wydaje mi się, że protocoli interfacemają prawie taką samą funkcjonalność.

  • Czy są między nimi jakieś różnice?

  • różne zastosowania w projekcie?

Zaktualizowano

Tak , przeczytałem powyższy link i nadal nie jestem pewien, jakie są różnice i zastosowanie między protocoli interface. Kiedy zadaję takie pytanie, chciałbym zobaczyć proste wyjaśnienie na ten temat. Czasami może być trudno uzyskać wszystko z dokumentacji.

Kok
źródło
1
Protokoły w języku Swift i interfejsy w Javie to te same pojęcia. Zobacz tutaj
Vivek Molkar
69
Myślę, że pytania takie jak to dotyczące różnic między językami są naprawdę przydatne do zrozumienia cech języka. I nie sądzę, aby prowadziły do ​​niepotrzebnych upartych odpowiedzi ani nie były łatwe do znalezienia odpowiedzi w dokumentacji. Dlatego nie sądzę, aby głosy negatywne w tej kwestii były uzasadnione.
Lii
1
Oto kilka krytycznych punktów z rzeczywistego świata dotyczących interfejsów Java - stackoverflow.com/a/41143492/294884 - które byłyby kluczowe dla każdego, kto jest nowy w Swift, wypróbowując Javę
Fattie
Z drugiej strony warto pamiętać, że cała racja bytu języka Swift polega na tym, że służy on do „programowania zorientowanego na protokół”. Wszystko robisz z „rozszerzeniami protokołów” w Swift wszędzie. Na przykład tutaj jest subtelna kwestia dotycząca języka Swift (tj. „O rozszerzeniach protokołów”), która ilustruje niektóre problemy.
Fattie
2
W Swift zamiast interfejsów używana jest nazwa protokołu, ponieważ w plikach nagłówkowych celu C (bezużyteczne duplikaty) z C nazywane są interfejsami
Alex78191

Odpowiedzi:

117

Zasadniczo protokoły są bardzo podobne do interfejsów Java, z wyjątkiem:

  • Protokoły Swift mogą również określać właściwości, które należy zaimplementować (np. Pola)
  • Szybkie protokoły muszą radzić sobie z wartością / odniesieniem za pomocą słowa kluczowego mutating (ponieważ protokoły mogą być implementowane przez struktury i klasy)
  • w dowolnym momencie można łączyć protokoły za pomocą słowa kluczowego protocol <>. Na przykład zadeklarowanie parametru funkcji, który musi być zgodny z protokołami A i B, jako:

.

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

Są to od razu widoczne różnice dla programisty Java (a przynajmniej to, co do tej pory zauważyłem).

Thomas Schar
źródło
13
słowo kluczowe protokołu <> ”: To naprawdę fajne! Myślę, że to właśnie nazywa się typem przecięcia w społeczności teorii systemów typów. W Javie możesz mieć takie typy tylko dla parametrów typu z wieloma ograniczeniami. Ten artykuł sugeruje wprowadzenie ich w Javie jako typu pierwszej klasy, ze składnią do oznaczania ich.
Lii
7
Niezłe podsumowanie. Kilka ważniejszych funkcji: Protokoły Swift mogą również określać powiązane wymagania dotyczące typu - np. Typ kolekcji ma powiązany typ indeksu lub metody porównywania porównywalnego typu wymagają parametru tego samego typu. W Swift 2.0 rozszerzenia protokołów mogą dodawać rzeczywistą funkcjonalność do typów, które spełniają wymagania protokołu.
rickster
2
@rickster Java 8 również może dodać implementację do interfejsu, oznaczając metodę default słowem kluczowym . Zobacz samouczek Oracle .
Basil Bourque
5
Słowo kluczowe protocol <> zostało teraz usunięte na rzecz znaku ampersand. Możesz więc napisać: niech c: A & B
Paul Robinson
2
W Swift zamiast interfejsów używana jest nazwa protokołu, ponieważ w plikach nagłówkowych celu C (bezużyteczne duplikaty) z C nazywane są interfejsami
Alex78191
33

Uzupełnienie odpowiedzi @Thomas Schar. Magia protokołu Swift pochodzi z rozszerzenia.

  • Protokoły Swift mogą uzyskać implementacje za pośrednictwem rozszerzenia (Swift
    2). Interfejs Java 8 może mieć domyślne implementacje, ale nie można tego zrobić „wstecz”.
  • W Swift można „wstecz” dodawać wymagania dotyczące protokołu (i
    jego implementacje, jeśli jest to potrzebne) do dowolnej klasy lub struktury.
  • Protokoły Swift nie są zgodne z ogólnym (tj. <..>) wzorcem dostosowywania, ale według schematu aliasów typu (tj. Typów skojarzonych). Może być mylące na początku, ale można tego uniknąć
    w niektórych przypadkach „ślepoty nawiasów ostrych”.
  • Swift ma zaawansowane dopasowywanie wzorców typów, dzięki czemu można bardzo dokładnie określić, gdzie i jak są stosowane wymagania i rozszerzenia protokołu. Może to być mylące, gdy pochodzi z Javy, ale ma dużą moc.
  • Dla właściwości / parametru można utworzyć szybki protokół (np. Celebrator: protokół)

Jedną rzeczą, która sprawiła, że ​​drapałem się po głowie przez kilka godzin, jest to, że nie wszystkie protokoły mogą być używane jako typy właściwości. Na przykład, jeśli masz protokół z typem aliasu, nie możesz bezpośrednio użyć go jako typu właściwości (ma to sens, gdy się nad tym zastanowisz, ale w Javie naprawdę chcemy mieć właściwość taką jak userrava: IDao).

Jeremy Chone
źródło
7
Również protokoły Swift mogą mieć opcjonalne elementy członkowskie, w przeciwieństwie do interfejsów Java.
eyeApps LLC
4
Drobną kwestią, która zawsze pojawia się w Swift, jest to, że nie ma (śmiesznie) żadnych funkcji abstrakcyjnych, więc po prostu mówisz "drukuj, zapomniałeś o tym!" ... stackoverflow.com/a/24111430/294884
Fattie
@Fattie. Możesz użyć słowa kluczowego „required” na funkcji, aby określić, że wymaga implementacji podklasy. A więc bardziej przypomina drobną ignorancję niż rzeczywisty punkt.
Dirk Bester
@DirkBester - pozdrawiam - czekaj, mówisz o inicjalizatorach ??
Fattie
Znowu @DirkBester Mogę mieć trochę zamieszania, ale nie można użyć requiredprzed funkcją w protokole, po prostu dostajesz 'required' may only be used on 'init' declarations...
Fattie