Mis à jour le 30/10/2017
  • 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Les contrôles d'accès

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Les contrôles d'accès vont permettre de restreindre l'utilisation de votre code source au travers d'autres fichiers et/ou modules. Ces contrôles pourront être faits directement sur vos types ou plus précisément sur vos propriétés ou méthodes.

Nous allons voir ici plusieurs niveaux d'accès à savoir : open, public, internal, fileprivate et private. Dans l'ordre, open est le moins restrictif et private est le plus restrictif.

open et public

Tout d’abord, avant d’aborderopen et  public  , je vais vous parler un peu de ce que c’est un module. Un module va regrouper tout un tas de fichiers sources au sein d’un seul projet. Par exemple, le TP que l’on a produit en deuxième partie est un module. Tous les fichiers ont été créés au sein d’un seul et même module : le nom de votre projet. Mais en Swift, rien n’empêche d’utiliser des modules au sein d’autres modules.

Pour se servir d’un module, il suffit d’utiliser le mot-clé  import  suivi du nom du module qu’on souhaite importer dans notre projet.

import NomModule

Revenons-en à nos moutons et concentrons nous sur  open  et  public  maintenant, vous voulez bien ? :p

open

Dès lors que l’on souhaite utiliser des classes et ses membres de classes (propriétés et méthodes) d’un module à un autre, c’est là qu’interviennent  open  et  public  et que l’on s’en sert. Pour indiquer qu’une classe ou ses membres de classe sont  open  , il faut préciser le mot-clé  open  avant tout.

open class NomClasse {
    open var nomVariable = 1
    
    open func nomFonction() {
    
    }
}

De telle façon, nous pourrions faire quelque chose de ce genre :

// Module A

open class ClasseModuleA {
    open var nomVariable = 1
    
    open func nomFonction() {
    
    }
}
 
// Module B
import ModuleA
 
let classeModuleA: ClasseModuleA

public

Comme pour  open  , ce niveau d’accès permet à une classe d’être utilisé en dehors du module de définition. La différence ici va se jouer sur l’héritage.  open  va se répercuter même sur les classes héritées, tandis que pour  public  , ce ne sera pas le cas. Voici un exemple pour mieux comprendre :

// Module A
open class ClasseA {
    open func A() {
    
    }
}
 
public class ClasseB {
    public func B() {
        
    }
}

// Module B
import ModuleA
 
class ClasseC : ClasseA {
    override func A() {
        // Succès
    }
}
 

class ClasseD : ClasseB {
    override func B() {
        // Erreur
    }
}

La classe  ClasseC  hérite de la classe  ClasseA  du module A qui est en  open  . De ce fait, nous avons le droit de surcharger la méthode  A()  .

A l’inverse,  ClasseD  hérite de la classe  ClasseB  du module A qui cette fois-ci est en  public  . De ce fait, il nous est impossible de surcharger la méthode  B()  . Une erreur sera retournée.

internal

internal  est le niveau d’accès par défaut. C’est-à-dire que sans que vous ayez besoin de faire quoi que ce soit, Swift mettra vos classes et vos membres de classes en  internal  . Vous pouvez toutefois préciser ce type pour vous en assurer.

Cette fois, cela autorise l’accès partout mais qu’au sein du module de définition et pas dans d’autres modules.

// Module A
internal class ClasseA {
    internal func A() {
    
    }
}
 
// Module B
import ModuleA
 
internal class ClasseB {
    internal func B() {
 
    }
}
 
let classeA: ClasseA = ClasseA() // Erreur
let classeB: ClasseB = ClasseB() // Succès

fileprivate

Les éléments  fileprivate  vont cette fois-ci se focaliser que sur le fichier source de définition. On pourra donc se servir de ces éléments au sein du même fichier mais pas dans un autre fichier.

// A.swift
class ClasseA {
    fileprivate func A() {
        print("Je ne serai appelé que depuis l'intérieur du fichier A.swift")
    }
}
 
// B.swift
class ClasseB {
    fileprivate func B() {
        
    }
}
 
let classeA: ClasseA = ClasseA()
classeA.A() // Erreur
let classeB: ClasseB = ClasseB()
classeB.B() // Succès

private

Enfin, pour finir, les éléments établis en tant que  private  eux ne seront accessible que dans le contexte dans lequel ils ont été définis (une classe, une structure, etc).

class ClasseA {
    private func A() {
        
    }
    
    func B() {
        A() // Succès
    }
}
 
// En dehors de la classe ClasseA
let classeA: ClasseA = ClasseA()
classeA.A() // Erreur

Pour résumer

  • open  : on s’en sert depuis n’importe où même dans les classes héritées

  • public  : pareil que pour  open  sauf pour les classes héritées

  • internal  : on s’en sert partout au sein d’un même module et pas ailleurs

  • fileprivate  : on s’en sert au sein d’un même fichier source et pas ailleurs

  • private  : on s’en sert qu’au sein du contexte utilisé (au sein d’une classe par exemple)

Exemple de certificat de réussite
Exemple de certificat de réussite