Bis jetzt haben wir die Grundlagen der Programmiersprache Swift behandelt. Wenn Sie mitverfolgen, sollten Sie jetzt ein solides Verständnis von Variablen, Konstanten, Funktionen und Schließungen haben. Es ist jetzt an der Zeit, das Erlernte anzuwenden und dieses Wissen auf die objektorientierten Strukturen von Swift anzuwenden.
Um die in diesem Tutorial behandelten Konzepte zu verstehen, müssen Sie über grundlegende Kenntnisse der objektorientierten Programmierung verfügen. Wenn Sie mit Klassen, Objekten und Methoden nicht vertraut sind, sollten Sie sich zuerst mit diesen Themen vertraut machen, bevor Sie mit diesem Lernprogramm fortfahren.
eBook: Objektorientierte Programmierung mit Swift
In dieser Lektion werden die grundlegenden Bausteine der objektorientierten Programmierung in Swift, Klassen und Strukturen untersucht. In Swift fühlen und verhalten sich Klassen und Strukturen sehr ähnlich, aber es gibt einige wichtige Unterschiede, die Sie verstehen müssen, um häufige Fallstricke zu vermeiden.
In Objective-C sind Klassen und Strukturen sehr unterschiedlich. Dies gilt nicht für Swift. In Swift können zum Beispiel sowohl Klassen als auch Strukturen Eigenschaften und Methoden haben. Im Gegensatz zu C-Strukturen können Strukturen in Swift erweitert werden und sie können auch protokollkonform sein.
Die naheliegende Frage lautet: "Was ist der Unterschied zwischen Klassen und Strukturen?" Wir werden diese Frage später in diesem Tutorial noch einmal besprechen. Lassen Sie uns zuerst erkunden, wie ein Kurs in Swift aussieht.
Bevor wir mit Klassen und Strukturen arbeiten, möchte ich einige häufig verwendete Begriffe in der objektorientierten Programmierung erläutern. Die Begriffe Klassen, Objekte, und Instanzen verwirren oft Menschen, die neu in der objektorientierten Programmierung sind. Daher ist es wichtig, dass Sie wissen, wie Swift diese Begriffe verwendet.
EIN Klasse ist eine Blaupause oder Vorlage für eine Instanz dieser Klasse. Der Begriff "Objekt" wird häufig verwendet, um sich auf eine Instanz einer Klasse zu beziehen. In Swift sind Klassen und Strukturen jedoch sehr ähnlich, und daher ist es einfacher und weniger verwirrend, den Begriff "Instanz" sowohl für Klassen als auch für Strukturen zu verwenden.
Früher in dieser Serie haben wir mit Funktionen gearbeitet. Im Kontext von Klassen und Strukturen bezeichnen wir Funktionen normalerweise als Methoden. Methoden sind also Funktionen, die zu einer bestimmten Klasse oder Struktur gehören. Im Kontext von Klassen und Strukturen können Sie beide Begriffe austauschbar verwenden, da jede Methode eine Funktion ist.
Lassen Sie uns die Füße nass werden und definieren Sie eine Klasse. Starten Sie Xcode und erstellen Sie einen neuen Spielplatz. Entfernen Sie den Inhalt des Spielplatzes und fügen Sie die folgende Klassendefinition hinzu.
Klasse Person
Das Klasse
Schlüsselwort zeigt an, dass wir eine Klasse mit dem Namen definieren Person. Die Implementierung der Klasse ist in geschweifte Klammern gehüllt. Obwohl die Person
Klasse ist in ihrer derzeitigen Form nicht sehr nützlich, es ist eine richtige, funktionelle Swift-Klasse.
Wie in den meisten anderen objektorientierten Programmiersprachen kann eine Klasse Eigenschaften und Methoden haben. In dem aktualisierten Beispiel definieren wir drei Eigenschaften:
Vorname
, eine variable Eigenschaft des Typs String?
Nachname
, eine variable Eigenschaft des Typs String?
Geburtsort
: eine konstante Eigenschaft des Typs String
Klasse Person var firstName: Zeichenfolge? var lastName: Zeichenfolge? let birthPlace = "Belgien"
Wie das Beispiel veranschaulicht, ähnelt das Definieren von Eigenschaften in einer Klassendefinition dem Definieren regulärer Variablen und Konstanten. Wir nehmen das var
Schlüsselwort zur Definition einer Variableneigenschaft und der Lassen
Schlüsselwort zum Definieren einer konstanten Eigenschaft.
Die oben genannten Eigenschaften sind auch als bekannt gespeicherte Eigenschaften. Später in dieser Serie erfahren wir mehr darüber berechnete Eigenschaften. Wie der Name schon sagt, sind gespeicherte Eigenschaften Eigenschaften, die von der Klasseninstanz gespeichert werden. Sie ähneln Eigenschaften in Objective-C.
Es ist wichtig zu beachten, dass jede gespeicherte Eigenschaft nach der Initialisierung einen Wert haben muss oder als optionaler Typ definiert werden muss. Im obigen Beispiel geben wir die Geburtsort
Eigenschaft einen Anfangswert von "Belgien"
. Dies teilt Swift mit, dass das Geburtsort-Eigentum vom Typ ist String
. Später in diesem Artikel werden wir die Initialisierung genauer betrachten und untersuchen, wie sie mit den Initialisierungseigenschaften verknüpft wird.
Obwohl wir das definiert haben Geburtsort
Eigenschaft als Konstante ist es möglich, ihren Wert während der Initialisierung von a zu ändern Person
Beispiel. Sobald die Instanz initialisiert wurde, wird die Geburtsort
Die Eigenschaft kann nicht mehr geändert werden, da wir die Eigenschaft mit der Eigenschaft als konstante Eigenschaft definiert haben Lassen
Stichwort.
Wir können einer Klasse über Funktionen oder Methoden Verhalten oder Funktionalität hinzufügen. In vielen Programmiersprachen, Methode wird anstelle von verwendet Funktion im Kontext von Klassen und Instanzen. Die Definition einer Methode ist fast identisch mit der Definition einer Funktion. Im nächsten Beispiel definieren wir die vollständiger Name()
Methode in der Person
Klasse.
Klasse Person var firstName: Zeichenfolge? var lastName: Zeichenfolge? let birthPlace = "Belgium" func fullName () -> String var parts: [String] = [] wenn letName = self.BirstName Parts + = [firstName]] ist, wenn let lastName = self.lastName parts + = [ lastName] return parts.joined (Trennzeichen: "")
Die Methode vollständiger Name()
ist in der Klassendefinition verschachtelt. Es akzeptiert keine Parameter und gibt a zurück String
. Die Umsetzung der vollständiger Name()
Methode ist unkompliziert. Durch die optionale Bindung, die wir zuvor in dieser Serie besprochen haben, greifen wir auf die in der Vorname
und Nachname
Eigenschaften.
Wir speichern den Vor- und Nachnamen der Person
Instanz in einem Array und verbinden die Teile mit einem Leerzeichen. Der Grund für diese etwas umständliche Implementierung sollte offensichtlich sein: Der Vor- und Nachname können leer sein, weshalb beide Eigenschaften vom Typ sind String?
.
Wir haben eine Klasse mit einigen Eigenschaften und einer Methode definiert. Wie erstellen wir eine Instanz von Person
Klasse? Wenn Sie mit Objective-C vertraut sind, werden Sie die Prägnanz des folgenden Snippets lieben.
let john = Person ()
Das Instanziieren einer Instanz einer Klasse ist dem Aufrufen einer Funktion sehr ähnlich. Um eine Instanz zu erstellen, folgt auf den Namen der Klasse ein Klammerpaar und der Rückgabewert wird einer Konstanten oder Variablen zugewiesen.
In unserem Beispiel die Konstante John
zeigt nun auf eine Instanz von Person
Klasse. Bedeutet das, dass wir keine Eigenschaften ändern können? Das nächste Beispiel beantwortet diese Frage.
john.firstName = "John" john.lastName = "Doe" john.birthPlace = "Frankreich"
Wir können auf die Eigenschaften einer Instanz mithilfe der Punktsyntax zugreifen. In dem Beispiel setzen wir Vorname
zu "John"
, Nachname
zu "Damhirschkuh"
, und Geburtsort
zu "Frankreich"
. Bevor wir auf der Grundlage des obigen Beispiels Schlussfolgerungen ziehen, müssen wir den Spielplatz auf Fehler prüfen.
Rahmen Vorname
und Nachname
scheint keine probleme zu verursachen. Aber zuweisen "Frankreich"
zum Geburtsort
Eigenschaft führt zu einem Fehler. Die Erklärung ist einfach.
Obwohl John
wird als Konstante deklariert, das hindert uns jedoch nicht daran, das zu ändern Person
Beispiel. Es gibt jedoch eine Einschränkung: Nach dem Initialisieren einer Instanz können nur variable Eigenschaften geändert werden. Eigenschaften, die als konstant definiert sind, können nicht geändert werden, nachdem ein Wert zugewiesen wurde.
Eine konstante Eigenschaft kann während der Initialisierung einer Instanz geändert werden. Während Geburtsort
Eigenschaft kann nicht einmal geändert werden a Person
Instanz erstellt wird, wäre die Klasse nicht sehr nützlich, wenn wir nur instanziieren könnten Person
Fälle mit einem Geburtsort von "Belgien". Lass uns das machen Person
Klasse etwas flexibler.
Die Initialisierung ist eine Phase in der Lebensdauer einer Instanz einer Klasse oder Struktur. Während der Initialisierung bereiten wir die Instanz für die Verwendung vor, indem ihre Eigenschaften mit Anfangswerten gefüllt werden. Die Initialisierung einer Instanz kann durch Implementierung eines Initialisierers, einer speziellen Methode, angepasst werden. Definieren wir einen Initialisierer für die Person
Klasse.
Klasse Person var firstName: Zeichenfolge? var lastName: Zeichenfolge? let birthPlace = "Belgium" init () birthPlace = "France"…
Wir haben einen Initialisierer definiert, wir haben jedoch einige Probleme. Schauen Sie sich den Fehler an, den der Compiler auf uns wirft.
Der Initialisierer ist nicht nur zwecklos, der Compiler warnt uns auch, dass wir den Wert von nicht ändern können Geburtsort
Eigenschaft, da es bereits einen Anfangswert hat. Wir können den Fehler beheben, indem Sie den Anfangswert von entfernen Geburtsort
Eigentum.
Klasse Person var firstName: Zeichenfolge? var lastName: Zeichenfolge? let birthPlace: String init () birthPlace = "France"…
Beachten Sie, dass der Name des Initialisierers, drin()
, ist nicht durch die vorangestellt func
Stichwort. Im Gegensatz zu den Initialisierern in Objective-C gibt ein Initialisierer in Swift nicht die Instanz zurück, die initialisiert wird.
Ein weiteres wichtiges Detail ist, wie wir das festlegen Geburtsort
Eigenschaft mit einem Anfangswert. Wir setzen die Geburtsort
Eigenschaft durch Verwendung des Eigenschaftennamens, aber es ist auch in Ordnung, expliziter zu sein.
init () self.birthPlace = "Frankreich"
Das selbst
Schlüsselwort bezieht sich auf die Instanz, die initialisiert wird. Das bedeutet, dass self.birthPlace
bezieht sich auf Geburtsort
Eigenschaft der Instanz. Wir können weglassen selbst
, Wie im ersten Beispiel, weil es keine Verwirrung darüber gibt, auf welche Eigenschaft wir uns beziehen. Dies ist jedoch nicht immer der Fall. Lass mich erklären, was ich meine.
Der von uns definierte Initialisierer ist im Moment nicht sehr nützlich und löst das Problem, mit dem wir begonnen haben, nicht: Es ist möglich, den Geburtsort einer Person während der Initialisierung zu definieren.
In vielen Situationen möchten Sie Initialisierungswerte an den Initialisierer übergeben, um die Instanz, die Sie instanziieren möchten, anzupassen. Dies ist möglich, indem Sie einen benutzerdefinierten Initialisierer erstellen, der ein oder mehrere Argumente akzeptiert. Im folgenden Beispiel erstellen wir einen benutzerdefinierten Initialisierer, der ein Argument akzeptiert, Geburtsort
, vom Typ String
.
init (birthPlace: String) self.birthPlace = birthPlace
Zwei Dinge sind hervorzuheben. Zuerst müssen wir auf das zugreifen Geburtsort
Eigentum durch self.birthPlace
um Mehrdeutigkeiten zu vermeiden, da der lokale Parametername gleich ist Geburtsort
. Zweitens, obwohl wir keinen externen Parameternamen angegeben haben, erstellt Swift standardmäßig einen externen Parameternamen, der dem lokalen Parameternamen entspricht.
Im folgenden Beispiel wird ein anderes instanziiert Person
Instanz durch Aufrufen des gerade definierten benutzerdefinierten Initialisierers.
let maxime = Person (birthPlace: "France") drucken (maxime.birthPlace)
Durch Übergeben eines Wertes für die Geburtsort
Mit dem Initialisierungsparameter können wir der Konstante einen benutzerdefinierten Wert zuweisen Geburtsort
Eigenschaft während der Initialisierung.
Wie in Objective-C kann eine Klasse oder Struktur mehrere Initialisierer haben. Im folgenden Beispiel erstellen wir zwei Person
Instanzen. In der ersten Zeile verwenden wir den Standardinitialisierer. In der zweiten Zeile verwenden wir den zuvor definierten benutzerdefinierten Initialisierer.
let p1 = Person () let p2 = Person (birthPlace: "France")
Die Strukturen sind überraschend ähnlich wie die Klassen, es gibt jedoch einige wesentliche Unterschiede. Beginnen wir mit der Definition einer Grundstruktur.
struct Wallet var dollar: Int var cents: Int
Auf den ersten Blick ist der einzige Unterschied die Verwendung von struct
Schlüsselwort anstelle von Klasse
Stichwort. Das Beispiel zeigt uns auch einen alternativen Ansatz, um den Eigenschaften Anfangswerte zu liefern. Anstatt einen Anfangswert für jede Eigenschaft festzulegen, können wir Eigenschaften im Initialisierer der Struktur einen Anfangswert zuweisen. Swift gibt keinen Fehler aus, da der Initialisierer außerdem den Anfangswert und den Typ jeder Eigenschaft ermittelt.
Sie beginnen sich zu fragen, was der Unterschied zwischen Klassen und Strukturen ist. Auf den ersten Blick sehen sie in Form und Funktion mit Ausnahme der Klasse
und struct
Schlüsselwörter. Es gibt jedoch einige wichtige Unterschiede.
Klassen unterstützen Vererbung, Strukturen dagegen nicht. Das folgende Beispiel veranschaulicht dies. Das Vererbungsdesignmuster ist für die objektorientierte Programmierung unverzichtbar und in Swift ein wesentlicher Unterschied zwischen Klassen und Strukturen.
Klasse Person var firstName: Zeichenfolge? var lastName: Zeichenfolge? let birthPlace: String init (birthPlace: String) self.birthPlace = birthPlace Klasse Schüler: Person var school: String? let student = Student (birthPlace: "Frankreich")
Im obigen Beispiel ist das Person
Klasse ist die übergeordnete oder Oberklasse der Student
Klasse. Dies bedeutet, dass die Student
Klasse erbt die Eigenschaften und das Verhalten von Person
Klasse. Die letzte Zeile veranschaulicht dies. Wir initialisieren ein Student
Instanz durch Aufrufen des benutzerdefinierten Initialisierers, der in definiert ist Person
Klasse.
Das folgende Konzept ist wahrscheinlich das wichtigste Konzept in Swift, das Sie heute lernen werden, der Unterschied zwischen Werttypen und Referenztypen. Strukturen sind Werttypen, dh sie werden nach Wert übergeben. Ein Beispiel veranschaulicht dieses Konzept am besten.
struct Point var x: Int var y: Int init (x: Int, y: Int) self.x = x self.y = y var point1 = Punkt (x: 0, y: 0) var point2 = Punkt1 Punkt1.x = 10 Druck (Punkt1.x) // 10 Druck (Punkt2.x) // 0
Wir definieren eine Struktur, Punkt
, um die Daten zu kapseln, um eine Koordinate in einem zweidimensionalen Raum zu speichern. Wir instanziieren Punkt 1
mit x
gleich 0
und y
gleich 0
. Wir vergeben Punkt 1
zu Punkt2
und setze das x
Koordinate von Punkt 1
zu 10
. Wenn wir das ausgeben x
Koordinate beider Punkte, entdecken wir, dass sie nicht gleich sind.
Strukturen werden als Wert übergeben, während Klassen als Referenz übergeben werden. Wenn Sie mit Swift weiterarbeiten möchten, müssen Sie die vorherige Aussage verstehen. Wenn wir vergeben haben Punkt 1
zu Punkt2
, Swift erstellte eine Kopie von Punkt 1
und es zugewiesen Punkt2
. Mit anderen Worten, Punkt 1
und Punkt2
jeder Punkt auf eine andere Instanz von Punkt
Struktur.
Wiederholen Sie diese Übung nun mit der Person
Klasse. Im folgenden Beispiel instanziieren wir a Person
Instanz setzen, ihre Eigenschaften festlegen, zuweisen person1
zu person2
, und aktualisieren Sie die Vorname
Eigentum von person1
. Um zu sehen, was Referenzübergabe für Klassen bedeutet, geben wir den Wert von aus Vorname
Eigentum von beiden Person
Instanzen.
var person1 = Person (birthPlace: "Belgium") person1.firstName = "Jane" person1.lastName = "Doe" var person2 = person1 person1.firstName = "Janine" drucken (person1.firstName!) // Janine print (person2. firstName!) // Janine
Das Beispiel zeigt, dass Klassen Referenztypen sind. Das bedeutet, dass person1
und person2
auf dasselbe verweisen oder verweisen Person
Beispiel. Durch Zuweisung person1
zu person2
, Swift erstellt keine Kopie von person1
. Das person2
Variable Punkte zum Selben Person
Beispiel person1
zeigt auf Wechseln Vorname
Eigentum von person1
betrifft auch die Vorname
Eigentum von person2
, weil sie dasselbe referenzieren Person
Beispiel.
Wie ich in diesem Artikel mehrfach erwähnt habe, sind Klassen und Strukturen sehr ähnlich. Was Klassen und Strukturen unterscheidet, ist sehr wichtig. Wenn die oben genannten Konzepte nicht klar sind, möchte ich Sie dazu ermutigen, den Artikel noch einmal zu lesen, um die Konzepte, die wir besprochen haben, auf sich wirken zu lassen.
In dieser Ausgabe von Swift From Scratch haben wir begonnen, die Grundlagen der objektorientierten Programmierung in Swift zu erforschen. Klassen und Strukturen sind die grundlegenden Bausteine der meisten Swift-Projekte, und wir werden in den nächsten Lektionen dieser Serie mehr darüber erfahren.
In der nächsten Lektion untersuchen wir Klassen und Strukturen, indem wir Eigenschaften und Vererbung näher betrachten.
Wenn Sie wissen möchten, wie Sie mit Swift 3 echte Apps programmieren können, lesen Sie unseren Kurs Erstellen von iOS-Apps mit Swift 3. Ob Sie nun mit der iOS-App vertraut sind oder ob Sie von Objective-C auf den Wechsel wechseln möchten Natürlich erhalten Sie mit Swift einen Einstieg in die App-Entwicklung.