1

POO : Les propriétés et méthodes

Cet article n'a pas été mis à jour depuis plus d'un an, il est possible que certaines informations ne soient plus à jour. Si vous rencontrez des erreurs ou des différences en le suivant, n'hésitez pas à commenter pour me le signaler.

Salut à tout le monde particulièrement aux lecteurs de ce blog ! On se retrouve en ce jour pluvieux / ensoleillé selon les heures pour creuser un peu plus les particularités des propriétés et des méthodes en Swift. Elles sont en effet plus complexe qu’il n’y parait et nous offre de nombreux réglages et autres personnalisations pour satisfaire toujours plus fortement notre désir irrationnel de contrôle sur la bonne exécution d’un travail immatériel. Alors sans plus attendre, repaissons nous de ce savoir bien juteux et alléchant !

Les sous-scipts

Une chose intéressante avec les propriétés des objets, c’est qu’il est possible de détecter facilement lorsqu’elles sont lues ou modifiées. Par exemple, imaginons que je souhaite stocker le nom et le prénom d’un individu (en l’occurrence Robert) dans un objet. Je veux pouvoir accéder à l’un et à l’autre indépendamment mais aussi ensemble pour obtenir une identité complète. Le moyen le plus simple et le plus efficace de le faire à ce moment là est d’appeler une méthode qui combinera les deux valeurs et me retournera un résultat. Mais je sais que je ne passerai pas d’arguments en particulier à cette méthode et au final elle agira plus comme une variable que l’on ne calcule que lorsqu’on en a besoin. C’est pour cet usage qu’il est possible de créer des sous-scripts directement dans des variables qui s’exécuteront en fonction de l’usage que l’on en fait.

Dans cet exemple, la propriété ne sera jamais que lue, par conséquent on peut lui implémenter le sous-script get qui retournera une valeur calculée au lieu d’une valeur stockée.

1
2
3
4
5
var nomComplet: String {
    get {
        return prenom + " " + nom
    }
}

Exactement comme une méthode, sauf que c’est une variable. Pourquoi faire me demandez-vous de votre regard perplexe ? L’avantage est d’améliorer la lisibilité du code, de cette façon on peut différencier plus facilement les méthodes qui effectuerons des actions notamment sur l’objet, des variables qui retourneront des valeurs. En théorie et en pratique c’est le même fonctionnement mais il est préférable de bien structurer son code pour le rendre plus facile à comprendre.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Personnage {
    var nom: String
    var prenom: String
   
    var nomComplet: String {
        get {
            return prenom + " " + nom
        }
    }
   
    init(nom _nom: String, prenom _prenom: String) {
        nom = _nom
        prenom = _prenom
    }
   
   
}

let robert = Personnage(nom: "Dupont", prenom: "Robert")
print(robert.nomComplet) // Robert Dupont

Il est tout à fait possible d’exécuter du code bien plus complexe dans le sous-script, même d’accéder à des variables ou méthodes de la classe, les modifier, etc… En revanche en l’implémentant il nous devient impossible d’assigner une quelconque valeur à la variable si l’on essaie de faire robert.nomComplet = "Philippe", Xcode nous affichera une erreur nous indiquant Cannot assign to property: ‘nomComplet’ is a get-only property.

Afin de pouvoir de nouveau écrire dans une variable, il va donc falloir lui implémenter un autre sous-script : set. De la même manière que get, il contiendra du code à exécuter lorsque l’on assignera une valeur à la variable :

1
2
3
4
5
6
7
8
var nomComplet: String {
    get {
        return prenom + " " + nom
    }
    set {
        print(newValue)
    }
}

Le code à l’intérieur du sous-script se verra automatiquement déclaré une constant nommée newValue qui contient la nouvelle valeur que l’on souhaite assigner à notre variable. Cependant si il nous est possible de récupérer cette valeur et d’en faire ce que l’on veut, elle ne sera jamais stockée dans la variable à laquelle elle est assignée. En effet, il ne peut pas y avoir de set sans get même si l’inverse est possible. Cela signifie que la variable possèdera systématiquement un code personnalisé pour retourner une valeur, aucune valeur brute n’y sera donc jamais stockée. Si l’on reprend notre exemple :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Personnage {
    var nom: String
    var prenom: String
   
    var nomComplet: String {
        get {
            return prenom + " " + nom
        }
        set {
            print(newValue)
        }
    }
   
    init(nom _nom: String, prenom _prenom: String) {
        nom = _nom
        prenom = _prenom
    }
   
   
}

let robert = Personnage(nom: "Dupont", prenom: "Robert")
print(robert.nomComplet)        // Robert Dupont

robert.nomComplet = "Philippe"  // Philippe
print(robert.nomComplet)        // Robert Dupont

La valeur de retour de la variable n’est pas modifiée ici car notre sous-script set ne stocke la valeur nulle part et se contente de l’afficher.

Le troisième et dernier sous-script disponible sur les variable est didSet. Celui-ci est un peu différent des autres car il est exclu de leur coopération, il n’est donc pas possible de le faire cohabiter avec get ou set sur une seule et même variable. Son fonctionnement est assez similaire à set, il contiendra du code qui s’exécutera une fois qu’une nouvelle valeur aura été assigné à la variable, à ceci près que cette dernière stockera la valeur et de manière générale fonctionnera comme une variable standard ; il est même possible de lui assigner une valeur par défaut. Dans ce sous-script, une constante est automatiquement fournie comme dans set mais s’appelle oldValue et contient cette fois-ci l’ancienne valeur de la variable avant son changement :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Personnage {
   
    var nom: String = "Robert" {
        didSet {
            print("Le nom était " + oldValue + " et est devenu " + nom)
        }
    }
   
}

let robert = Personnage()
print(robert.nom)        // Robert

robert.nom = "Philippe"
// Le nom était Robert et est devenu Philippe

Les propriétés statiques

Il existe des propriétés dans les classes qui possèdent un fonctionnement particulier. Qu’elles soient des variables ou des fonctions, il est possible de les appeler et d’y accéder sans avoir d’instance initialisée de la classe. On les appelle des propriétés statiques, et elle se déclarent comme toutes les autres à l’exception du mot clé static qui les précède. Ces propriétés sont accessibles comme des sous-éléments du type associé à la classe contrairement à une variable contenant une variable instanciée :

1
2
3
4
5
6
7
8
9
class Test {
   
    static let propriete = "Valeur statique"
    static func fonction() {
        // fonction statique
    }
}

print(Test.propriete) // valeur statique

En accédant à Test.propriete, on comprend bien que la variable en question est pré-initialisée sur le type de la classe, si l’on tente d’y accéder depuis une instance comme cela :

1
2
var testClasse = Test()
testClasse.propriete

Xcode nous retournera l’erreur Static member ‘propriete’ cannot be used on instance of type ‘Test’. Elles sont parfaitement indépendantes du reste de la classe, ce qui veut dire par exemple qu’elles ne peuvent pas accéder les autres propriétés non-statiques, et ces dernières ne peuvent pas accéder aux propriétés statiques. Si on le fait, alors Xcode nous retournera la même erreur.

Elles sont souvent utilisées pour accéder à des instances pré-créées de la classe, des constantes ou paramètres lié à l’objet ou des actions traitant de l’objet qui ne requièrent pas de l’instancier mais qu’on ne saurait pas vraiment où ranger ailleurs :

1
2
3
4
5
6
7
8
9
10
11
12
class Personnage {
    var nom: String
   
    init(nom _nom : String) {
        nom = _nom
    }
   
    static let robert = Personnage(nom: "Robert")
   
}

let robert = Personnage.robert // retourne une instance de la classe Personnage

 

Parfait ! Nous avons fait plus ou moins le tour des particularités liés aux classe, nous allons maintenant pouvoir nous attaquer aux autres types d’objets, les différences et leurs utilités. Pour l’instant, je vous libère de votre attention et vous laisse appréhender les multiples possibilités qu’offrent les classe, je vous dis à très bientôt pour la suite des aventures !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *