Swift From Scratch Introduction aux classes et aux structures

Jusqu'à présent, nous avons couvert les bases du langage de programmation Swift. Si vous avez suivi, vous devriez maintenant avoir une solide compréhension des variables, des constantes, des fonctions et des fermetures. Il est maintenant temps d'utiliser ce que nous avons appris et d'appliquer ces connaissances aux structures orientées objet de Swift..

Pour comprendre les concepts abordés dans ce didacticiel, il est important que vous maîtrisiez les bases de la programmation orientée objet. Si vous n'êtes pas familier avec les classes, les objets et les méthodes, je vous recommande de lire ces sujets avant de poursuivre ce didacticiel..

eBook: Programmation orientée objet avec Swift

1. Introduction

Dans cette leçon, nous allons explorer les éléments fondamentaux de la programmation orientée objet dans Swift, ses classes et ses structures. Dans Swift, les classes et les structures ont le même comportement et le même comportement, mais vous devez comprendre un certain nombre de différences essentielles pour éviter les pièges courants..

En Objective-C, les classes et les structures sont très différentes. Ce n'est pas vrai pour Swift. Dans Swift, par exemple, les classes et les structures peuvent avoir des propriétés et des méthodes. Contrairement aux structures en C, les structures dans Swift peuvent être étendues et conformes aux protocoles..

La question évidente est: "Quelle est la différence entre les classes et les structures?" Nous reviendrons sur cette question plus tard dans ce tutoriel. Voyons d'abord à quoi ressemble une classe dans Swift.

2. Terminologie

Avant de commencer à travailler avec des classes et des structures, j'aimerais clarifier quelques termes couramment utilisés dans la programmation orientée objet. Les termes Des classes, objets, et les instances confondent souvent les nouveaux venus avec la programmation orientée objet. Il est donc important que vous sachiez comment Swift utilise ces termes..

Objets et instances

UNE classe est un plan ou un modèle pour une instance de cette classe. Le terme "objet" est souvent utilisé pour désigner une instance d'une classe. Dans Swift, cependant, les classes et les structures sont très similaires, il est donc plus facile et moins déroutant d’utiliser le terme "instance" pour les classes et les structures..

Méthodes et fonctions

Plus tôt dans cette série, nous avons utilisé des fonctions. Dans le contexte des classes et des structures, nous appelons généralement les fonctions des méthodes. En d'autres termes, les méthodes sont des fonctions appartenant à une classe ou à une structure particulière. Dans le contexte des classes et des structures, vous pouvez utiliser les deux termes de manière interchangeable, chaque méthode étant une fonction..

3. Définir une classe

Mouillons nos pieds et définissons une classe. Lancez Xcode et créez un nouveau terrain de jeu. Supprimez le contenu du terrain de jeu et ajoutez la définition de classe suivante.

classe Personne 

le classe mot-clé indique que nous définissons une classe nommée La personne. L'implémentation de la classe est entourée d'une paire d'accolades. Même si le La personne La classe n’est pas très utile dans sa forme actuelle, c’est une classe Swift adéquate et fonctionnelle.

Propriétés

Comme dans la plupart des autres langages de programmation orientés objet, une classe peut avoir des propriétés et des méthodes. Dans l'exemple mis à jour ci-dessous, nous définissons trois propriétés:

  • Prénom, une propriété de type variable Chaîne?
  • nom de famille, une propriété de type variable Chaîne?
  • Lieu de naissance: une propriété constante de type Chaîne
classe Person var firstName: String? var lastName: String? let birthPlace = "Belgique"

Comme l'illustre l'exemple, la définition de propriétés dans une définition de classe est similaire à la définition de variables et de constantes régulières. Nous utilisons le var mot-clé pour définir une propriété de variable et la laisser mot clé pour définir une propriété constante.

Les propriétés ci-dessus sont également appelées propriétés stockées. Plus tard dans cette série, nous apprenons à propos de propriétés calculées. Comme son nom l'indique, les propriétés stockées sont des propriétés stockées par l'instance de la classe. Ils sont similaires aux propriétés dans Objective-C.

Il est important de noter que chaque propriété stockée doit avoir une valeur après l'initialisation ou être définie en tant que type facultatif. Dans l'exemple ci-dessus, nous donnons au Lieu de naissance propriété une valeur initiale de "Belgique". Ceci indique à Swift que la propriété de lieu de naissance est de type Chaîne. Plus loin dans cet article, nous examinons l'initialisation plus en détail et explorons son lien avec les propriétés d'initialisation..

Même si nous avons défini le Lieu de naissance propriété en tant que constante, il est possible de changer sa valeur lors de l'initialisation d'un La personne exemple. Une fois l'instance initialisée, le Lieu de naissance la propriété ne peut plus être modifiée puisque nous avons défini la propriété comme une propriété constante avec le laisser mot-clé.

Les méthodes

Nous pouvons ajouter un comportement ou une fonctionnalité à une classe via des fonctions ou des méthodes. Dans de nombreux langages de programmation, méthode est utilisé à la place de une fonction dans le contexte des classes et des instances. Définir une méthode est presque identique à définir une fonction. Dans l'exemple suivant, nous définissons le nom complet() méthode dans le La personne classe.

classe Person var firstName: String? var lastName: String? let birthPlace = "Belgique" func fullName () -> String var parts: [String] = [] si let firstName = self.firstName parts + = [firstName] si let lastName = self.lastName parts + = [ lastName] return parts.joined (separator: "")

La méthode nom complet() est imbriqué dans la définition de la classe. Il n'accepte aucun paramètre et retourne un Chaîne. La mise en œuvre de la nom complet() méthode est simple. Grâce à la liaison facultative, dont nous avons déjà parlé dans cette série, nous avons accès aux valeurs stockées dans Prénom et nom de famille Propriétés.

Nous stockons le prénom et le nom de famille du La personne exemple dans un tableau et joindre les parties avec un espace. La raison de cette implémentation quelque peu délicate devrait être évidente: le nom et le prénom peuvent être vides, ce qui explique pourquoi les deux propriétés sont de type. Chaîne?.

Instanciation

Nous avons défini une classe avec quelques propriétés et une méthode. Comment crée-t-on une instance de La personne classe? Si vous connaissez Objective-C, vous allez adorer la concision de l'extrait suivant..

let john = Person ()

Instancier une instance d'une classe est très similaire à invoquer une fonction. Pour créer une instance, le nom de la classe est suivi d'une paire de parenthèses et la valeur renvoyée est affectée à une constante ou à une variable..

Dans notre exemple, la constante John pointe maintenant vers une instance du La personne classe. Cela signifie-t-il que nous ne pouvons modifier aucune de ses propriétés? L'exemple suivant répond à cette question.

john.firstName = "John" john.lastName = "Doe" john.birthPlace = "France"

Nous pouvons accéder aux propriétés d'une instance en utilisant la commodité de la syntaxe à points. Dans l'exemple, nous définissons Prénom à "John", nom de famille à "Biche", et Lieu de naissance à "France". Avant de tirer des conclusions basées sur l'exemple ci-dessus, nous devons vérifier les erreurs éventuelles sur le terrain de jeu..

Réglage Prénom et nom de famille ne semble pas causer de problèmes. Mais assigner "France" au Lieu de naissance la propriété entraîne une erreur. L'explication est simple.

Même si John est déclaré comme une constante, cela ne nous empêche pas de modifier le La personne exemple. Une mise en garde toutefois: seules les propriétés de variable peuvent être modifiées après l'initialisation d'une instance. Les propriétés définies comme constantes ne peuvent plus être modifiées une fois qu'une valeur est attribuée.

Une propriété constante peut être modifiée lors de l'initialisation d'une instance. Tandis que le Lieu de naissance la propriété ne peut pas être changée une fois La personne par exemple, la classe ne serait pas très utile si nous ne pouvions instancier que La personne exemples avec un lieu de naissance de "Belgique". Faisons le La personne classe un peu plus flexible.

Initialisation

L'initialisation est une phase de la vie d'une instance de classe ou de structure. Lors de l'initialisation, nous préparons l'instance pour son utilisation en renseignant ses propriétés avec les valeurs initiales. L'initialisation d'une instance peut être personnalisée en implémentant un initialiseur, un type de méthode spécial. Définissons un initialiseur pour le La personne classe.

classe Person var firstName: String? var lastName: String? let birthPlace = "Belgique" init () birthPlace = "France"…

Nous avons défini un initialiseur, mais nous rencontrons plusieurs problèmes. Jetez un coup d'oeil à l'erreur que le compilateur nous lance.

L’initialiseur est non seulement inutile, le compilateur nous avertit également que nous ne pouvons pas modifier la valeur de Lieu de naissance propriété car il a déjà une valeur initiale. Nous pouvons résoudre l’erreur en supprimant la valeur initiale de Lieu de naissance propriété.

classe Person var firstName: String? var lastName: String? let birthPlace: String init () birthPlace = "France"…

Notez que le nom de l'initialiseur, init (), n'est pas précédé par le func mot-clé. Contrairement aux initialiseurs d'Objective-C, un initialiseur de Swift ne renvoie pas l'instance en cours d'initialisation..

Un autre détail important est la manière dont nous définissons la Lieu de naissance propriété avec une valeur initiale. Nous avons mis le Lieu de naissance propriété en utilisant le nom de la propriété, mais il est également bon d'être plus explicite comme celui-ci.

init () self.birthPlace = "France"

le soi mot-clé fait référence à l'instance en cours d'initialisation. Cela signifie que self.birthPlace se réfère à la Lieu de naissance propriété de l'instance. Nous pouvons omettre soi, comme dans le premier exemple, car il n'y a pas de confusion quant à la propriété à laquelle nous faisons référence. Ce n'est pas toujours le cas, cependant. Laisse-moi expliquer ce que je veux dire.

Paramètres

L'initialiseur que nous avons défini n'est pas très utile pour le moment et ne résout pas le problème avec lequel nous avons commencé: être capable de définir le lieu de naissance d'une personne pendant l'initialisation.. 

Dans de nombreuses situations, vous souhaitez transmettre les valeurs initiales à l'initialiseur pour personnaliser l'instance que vous instanciez. Cela est possible en créant un initialiseur personnalisé qui accepte un ou plusieurs arguments. Dans l'exemple suivant, nous créons un initialiseur personnalisé qui accepte un argument, Lieu de naissance, de type Chaîne.

init (birthPlace: String) self.birthPlace = birthPlace

Deux choses méritent d'être soulignées. Premièrement, nous devons accéder à la Lieu de naissance propriété à travers self.birthPlace pour éviter toute ambiguïté puisque le nom du paramètre local est égal à Lieu de naissance. Deuxièmement, même si nous n’avons pas spécifié de nom de paramètre externe, Swift crée par défaut un nom de paramètre externe égal au nom de paramètre local..

Dans l'exemple suivant, nous instancions un autre La personne par exemple en invoquant l'initialiseur personnalisé que nous venons de définir.

let maxime = Person (birthPlace: "France") print (maxime.birthPlace)

En passant une valeur pour le Lieu de naissance paramètre à l'initialiseur, nous pouvons attribuer une valeur personnalisée à la constante Lieu de naissance propriété pendant l'initialisation.

Plusieurs initialiseurs

Comme dans Objective-C, une classe ou une structure peut avoir plusieurs initialiseurs. Dans l'exemple suivant, nous créons deux La personne les instances. Dans la première ligne, nous utilisons l'initialiseur par défaut. Dans la deuxième ligne, nous utilisons l'initialiseur personnalisé défini précédemment.

let p1 = Person () let p2 = Person (BirthPlace: "France")

4. Définir une structure

Les structures ressemblent étonnamment aux classes, mais il y a quelques différences principales. Commençons par définir une structure de base.

struct Wallet var dollars: Int var cents: Int

À première vue, la seule différence est l’utilisation de la struct mot clé au lieu de classe mot-clé. L'exemple nous montre également une approche alternative pour fournir des valeurs initiales aux propriétés. Au lieu de définir une valeur initiale pour chaque propriété, nous pouvons donner aux propriétés une valeur initiale dans l'initialiseur de la structure. Swift ne génère pas d'erreur, car il inspecte également l'initialiseur pour déterminer la valeur initiale et le type de chaque propriété..

5. Classes et structures

Vous pouvez commencer à vous demander quelle est la différence entre les classes et les structures. À première vue, leur forme et leur fonction sont identiques, à l’exception de la classe et struct mots clés. Il existe un certain nombre de différences clés, bien que.

Héritage

Les classes supportent l'héritage, contrairement aux structures. L'exemple suivant illustre cela. Le modèle de conception d'héritage est indispensable dans la programmation orientée objet et, dans Swift, il constitue une différence essentielle entre les classes et les structures..

classe Person var firstName: String? var lastName: String? let birthPlace: String init (birthPlace: String) self.birthPlace = BirthPlace classe Étudiant: Personne var school: String?  let student = Student (BirthPlace: "France")

Dans l'exemple ci-dessus, le La personne la classe est le parent ou la superclasse de la Étudiant classe. Cela signifie que le Étudiant la classe hérite des propriétés et du comportement du La personne classe. La dernière ligne illustre cela. Nous initialisons un Étudiant exemple en appelant l’initialiseur personnalisé défini dans le La personne classe.

Copie et référencement

Le concept suivant est probablement le concept le plus important de Swift que vous apprendrez aujourd'hui, la différence entre types de valeur et types de référence. Les structures sont des types de valeur, ce qui signifie qu'elles sont passées par valeur. Un exemple illustre le mieux ce concept.

struct Point var x: Int var y: Int init (x: Int, y: Int) self.x = x self.y = y var point1 = Point (x: 0, y: 0) var point2 = point1 point1.x = 10 print (point1.x) // 10 print (point2.x) // 0

Nous définissons une structure, Point, pour encapsuler les données afin de stocker une coordonnée dans un espace à deux dimensions. Nous instancier point1 avec X égal à 0 et y égal à 0. Nous assignons point1 à point2 et mettre le X coordonnée de point1 à dix. Si nous sortons le X coordonnée des deux points, nous découvrons qu'ils ne sont pas égaux.

Les structures sont passées par valeur, alors que les classes sont passées par référence. Si vous envisagez de continuer à travailler avec Swift, vous devez comprendre la déclaration précédente. Quand nous avons assigné point1 à point2, Swift a créé une copie de point1 et l'a assigné à point2. En d'autres termes, point1 et point2 chaque point à une instance différente du Point structure.

Répétons maintenant cet exercice avec le La personne classe. Dans l'exemple suivant, nous instancions un La personne par exemple, définir ses propriétés, attribuer personne1 à personne2, et mettre à jour le Prénom propriété de personne1. Pour voir ce que signifie passer par référence pour les classes, nous affichons la valeur de Prénom propriété des deux La personne les instances.

var person1 = Person (birthPlace: "Belgique") person1.firstName = "Jane" person1.lastName = "Doe" var person2 = person1 person1.firstName = "Janine" print (person1.firstName!) // Janine print (person2. prenom!) // Janine

L'exemple prouve que les classes sont des types de référence. Cela signifie que personne1 et personne2 se référer ou référencer le même La personne exemple. En assignant personne1 à personne2, Swift ne crée pas une copie de personne1. le personne2 variable points à la même La personne exemple personne1 pointe vers. Changer le Prénom propriété de personne1 affecte également le Prénom propriété de personne2, parce qu'ils font référence au même La personne exemple.

Comme je l'ai mentionné à plusieurs reprises dans cet article, les classes et les structures sont très similaires. Ce qui sépare les classes et les structures est très important. Si les concepts ci-dessus ne sont pas clairs, je vous encourage à lire l'article une nouvelle fois pour que les concepts que nous avons décrits soient intégrés..

Conclusion

Dans cet article de Swift From Scratch, nous avons commencé à explorer les bases de la programmation orientée objet dans Swift. Les classes et les structures sont les éléments de base de la plupart des projets Swift, et nous en apprendrons davantage à leur sujet dans les prochaines leçons de cette série..

Dans la leçon suivante, nous poursuivons notre exploration des classes et des structures en examinant de plus près les propriétés et les héritages..

Si vous souhaitez apprendre à utiliser Swift 3 pour coder des applications réelles, consultez notre cours Créer des applications iOS avec Swift 3. Que vous débutiez dans le développement d'applications iOS ou que vous souhaitiez passer de Objective-C à un autre bien sûr, vous allez commencer avec Swift pour le développement d'applications.