Vergleichen Sie das Protokoll in Swift mit der Schnittstelle in Java

149

Ich gehe das iOS-Tutorial von der Apple-Entwicklerseite durch .

Es scheint mir, dass protocolund interfacefast die gleiche Funktionalität haben.

  • Gibt es Unterschiede zwischen den beiden?

  • die unterschiedliche Verwendung im Projekt?

Aktualisiert

Ja , ich habe den obigen Link gelesen und bin mir immer noch nicht sicher, was die Unterschiede und die Verwendung zwischen protocolund sind interface. Wenn ich eine solche Frage stelle, würde ich gerne eine einfache Erklärung zum Thema sehen. Manchmal kann es schwierig sein, alles aus der Dokumentation herauszuholen.

Brötchen
quelle
1
Protokolle in Swift und Schnittstellen in Java sind dieselben Konzepte. Siehe hier
Vivek Molkar
69
Ich denke, Fragen wie diese über Unterschiede zwischen Sprachen sind wirklich nützlich, um Sprachmerkmale zu verstehen. Und ich denke nicht, dass sie zu unnötigen Antworten führen, und es ist auch nicht sehr einfach, die Antwort in der Dokumentation zu finden. Daher halte ich die Abstimmungen zu dieser Frage nicht für gerechtfertigt.
Lii
1
Hier sind ein paar wichtige Punkte aus der Praxis über Java-Schnittstellen - stackoverflow.com/a/41143492/294884 -, die für jeden, der Swift noch nicht
Fattie
In der anderen Richtung ist es wichtig, sich daran zu erinnern, dass die gesamte Existenzberechtigung von Swift darin besteht, dass es sich um eine "protokollorientierte Programmierung" handelt. Sie machen alles mit "Protokollerweiterungen" in Swift allgegenwärtig. Zum Beispiel ist hier ein subtiles Problem über Swift (dh: "über Protokollerweiterungen"), das einige der Probleme veranschaulicht.
Fattie
2
In Swift wird anstelle von Schnittstellen der Protokollname verwendet, da in Objective C Header-Dateien (nutzlose Duplikate) von C als Schnittstellen bezeichnet werden
Alex78191

Antworten:

117

Im Wesentlichen sind Protokolle Java-Schnittstellen sehr ähnlich, mit Ausnahme von:

  • Swift-Protokolle können auch Eigenschaften angeben, die implementiert werden müssen (dh Felder).
  • Schnelle Protokolle müssen sich mit Wert / Referenz unter Verwendung des mutierenden Schlüsselworts befassen (da Protokolle von Strukturen und Klassen implementiert werden können).
  • Sie können Protokolle jederzeit mit dem Schlüsselwort protocol <> kombinieren. Beispiel: Deklarieren eines Funktionsparameters, der Protokoll A und B entsprechen muss, als:

.

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

Dies sind die sofort offensichtlichen Unterschiede für einen Java-Entwickler (oder zumindest das, was ich bisher entdeckt habe).

Thomas Schar
quelle
13
" the protocol <> keyword ": Das ist echt cool! Ich denke, dies wird in der Community der Typsystemtheorie als Schnittpunkttyp bezeichnet . In Java können Sie solche Typen nur für Typparameter mit mehreren Grenzen haben. In diesem Artikel wird vorgeschlagen , sie in Java als erstklassigen Typ einzuführen, wobei die Syntax sie bezeichnet.
Lii
7
Schöne Zusammenfassung. Einige weitere wichtige Funktionen: Swift-Protokolle können auch zugehörige Typanforderungen angeben - z. B. hat ein Sammlungstyp einen zugeordneten Indextyp oder die Vergleichsmethoden eines vergleichbaren Typs erfordern einen Parameter desselben Typs. In Swift 2.0 können Protokollerweiterungen Typen, die den Anforderungen eines Protokolls entsprechen, tatsächliche Funktionen hinzufügen.
Rickster
2
Auch @rickster Java 8 kann einer Schnittstelle eine Implementierung hinzufügen, indem eine Methode mit dem default Schlüsselwort versehen wird . Siehe das Oracle-Tutorial .
Basil Bourque
5
Das Schlüsselwort protocol <> wurde jetzt zugunsten des kaufmännischen Und entfernt. Sie können also schreiben: Lassen Sie c: A & B
Paul Robinson
2
In Swift wird anstelle von Schnittstellen der Protokollname verwendet, da in Objective C Header-Dateien (nutzlose Duplikate) von C als Schnittstellen bezeichnet werden
Alex78191
33

Ergänzung der Antwort von @Thomas Schar. Die Magie des Swift-Protokolls kommt von der Erweiterung.

  • Swift-Protokolle können Implementierungen über die Erweiterung (Swift
    2) erhalten. Die Java 8-Schnittstelle kann Standardimplementierungen haben, kann jedoch nicht "rückwirkend" durchgeführt werden.
  • In Swift können Sie
    jeder Klasse oder Struktur "rückwirkend" Protokollanforderungen (und gegebenenfalls deren Implementierungen) hinzufügen .
  • Schnelle Protokolle folgen nicht dem generischen (dh <..>) Anpassungsmuster, sondern einem Typealias-Schema (dh zugehörigen Typen). Kann zu Beginn verwirrend sein, kann aber
    in einigen Fällen "Blindheit der spitzen Klammern" vermeiden .
  • Swift verfügt über einen erweiterten Musterabgleich, der es ermöglicht, genau zu bestimmen, wo und wie Protokollanforderungen und -erweiterungen angewendet werden. Es kann verwirrend sein, wenn man aus Java kommt, aber es hat viel Kraft.
  • Ein schnelles Protokoll kann für eine Eigenschaft / einen Parameter erstellt werden (dh Celebrator: Protokoll).

Eine Sache, die mich ein paar Stunden lang am Kopf kratzen ließ, ist, dass nicht alle Protokolle als Eigenschaftstypen verwendet werden können. Wenn Sie beispielsweise ein Protokoll mit Typealias haben, können Sie es nicht direkt als Eigenschaftstyp verwenden (es ist sinnvoll, wenn Sie darüber nachdenken, aber aus Java möchten wir wirklich eine Eigenschaft wie userDao: IDao haben).

Jeremy Chone
quelle
7
Im Gegensatz zu Java-Schnittstellen können Swift-Protokolle auch optionale Mitglieder haben.
eyeApps LLC
4
Ein kleiner Punkt, der in Swift immer auftaucht, ist, dass es (lächerlich) keine abstrakten Funktionen gibt, also gehen Sie einfach zu "Drucken, Sie haben diese vergessen!" ... stackoverflow.com/a/24111430/294884
Fattie
@ Fattie. Sie können das Schlüsselwort "required" für eine Funktion verwenden, um anzugeben, dass eine Unterklassenimplementierung erforderlich ist. Also eher eine kleine Unwissenheit als ein tatsächlicher Punkt.
Dirk Bester
@ KirkBester - Prost - warte, du sprichst mit Initialisierern?
Fattie
Wieder @DirkBester Ich kann einige Verwirrung haben, aber man kann nicht requiredvor einer Funktion in einem Protokoll verwenden, Sie bekommen nur 'required' may only be used on 'init' declarations...
Fattie