Swift - Contrôle d'accès

Pour restreindre l'accès aux blocs de code, aux modules et à l'abstraction se fait via le contrôle d'accès. Les classes, structures et énumérations sont accessibles en fonction de leurs propriétés, méthodes, initialiseurs et indices par des mécanismes de contrôle d'accès. L'accès aux constantes, variables et fonctions d'un protocole est restreint et autorisé comme global et local via le contrôle d'accès. Le contrôle d'accès appliqué aux propriétés, types et fonctions peut être appelé «entités».

Le modèle de contrôle d'accès est basé sur des modules et des fichiers source.

Le module est défini comme une seule unité de distribution de code et peut être importé à l'aide du mot-clé «import». Un fichier source est défini comme un fichier de code source unique avec dans un module pour accéder à plusieurs types et fonctions.

Trois niveaux d'accès différents sont fournis par Swift 4 language. Il s'agit d'un accès public, interne et privé.

S. Non Niveaux d'accès et définition
1

Public

Permet aux entités d'être traitées dans n'importe quel fichier source de leur module de définition, un fichier source d'un autre module qui importe le module de définition.

2

Internal

Permet aux entités d'être utilisées dans n'importe quel fichier source à partir de leur module de définition, mais pas dans un fichier source en dehors de ce module.

3

Private

Limite l'utilisation d'une entité à son propre fichier source de définition. L'accès privé joue le rôle de masquer les détails d'implémentation d'une fonctionnalité de code spécifique.

Syntaxe

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Contrôle d'accès pour les types de fonction

Certaines fonctions peuvent avoir des arguments déclarés à l'intérieur de la fonction sans aucune valeur de retour. Le programme suivant déclare a et b comme arguments de la fonction sum (). À l'intérieur de la fonction elle-même, les valeurs des arguments a et b sont passées en appelant la fonction d'appel sum () et ses valeurs sont affichées, éliminant ainsi les valeurs de retour. Pour rendre le type de retour de la fonction privé, déclarez le niveau d'accès global de la fonction avec le modificateur private.

private func sum(a: Int, b: Int) {
   let a = a + b
   let b = a - b
   print(a, b)
}

sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

30 20
50 40
30 24

Contrôle d'accès pour les types d'énumération

public enum Student {
   case Name(String)
   case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
   
}

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

Student Marks are: 98,97,95

L'énumération en langage Swift 4 reçoit automatiquement le même niveau d'accès pour les cas individuels d'une énumération. Pensez par exemple à accéder au nom des étudiants et aux marques sécurisées dans trois matières: le nom de l'énumération est déclaré comme étudiant et les membres présents dans la classe enum sont nom qui appartient à la chaîne de type de données, les marques sont représentées comme mark1, mark2 et mark3 de type de données Integer. Pour accéder au nom de l'élève ou aux notes qu'il a notées. Maintenant, le boîtier de commutation imprimera le nom de l'étudiant si ce bloc de cas est exécuté, sinon il imprimera les marques sécurisées par l'étudiant. Si les deux conditions échouent, le bloc par défaut sera exécuté.

Contrôle d'accès pour les sous-classes

Swift 4 permet à l'utilisateur de sous-classer n'importe quelle classe accessible dans le contexte d'accès actuel. Une sous-classe ne peut pas avoir un niveau d'accès plus élevé que sa superclasse. L'utilisateur n'a pas le droit d'écrire une sous-classe publique d'une superclasse interne.

public class cricket {
   internal func printIt() {
      print("Welcome to Swift 4 Super Class")
   }
}

internal class tennis: cricket {
   override internal func printIt() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.printIt()

let tennisinstance = tennis()
tennisinstance.printIt()

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

Welcome to Swift Super Class
Welcome to Swift Sub Class

Contrôle d'accès pour les constantes, les variables, les propriétés et les indices

La constante, la variable ou la propriété Swift 4 ne peut être définie comme publique que son type. Il n'est pas valide d'écrire une propriété publique avec un type privé. De même, un indice ne peut pas être plus public que son index ou son type de retour.

Lorsqu'une constante, une variable, une propriété ou un indice utilise un type privé, la constante, la variable, la propriété ou l'indice doit également être marqué comme privé -

private var privateInstance = SomePrivateClass()

Getters et Setters

Les récupérateurs et les setters pour les constantes, les variables, les propriétés et les indices reçoivent automatiquement le même niveau d'accès que la constante, la variable, la propriété ou l'indice auquel ils appartiennent.

class Samplepgm {
   var counter: Int = 0{
      willSet(newTotal) {
         print("Total Counter is: \(newTotal)")
      }
      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

Contrôle d'accès pour les initialiseurs et les initialiseurs par défaut

Les initialiseurs personnalisés peuvent se voir attribuer un niveau d'accès inférieur ou égal au type qu'ils initialisent. Un initialiseur requis doit avoir le même niveau d'accès que la classe à laquelle il appartient. Les types de paramètres d'un initialiseur ne peuvent pas être plus privés que son propre niveau d'accès.

Pour déclarer chaque sous-classe du mot clé initialize 'required' doit être défini avant la fonction init ().

class classA {
   required init() {
      let a = 10
      print(a)
   }
}
class classB: classA {
   required init() {
      let b = 30
      print(b)
   }
}
let res = classA()
let print = classB()

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

10
30
10

Un initialiseur par défaut a le même niveau d'accès que le type qu'il initialise, sauf si ce type est défini comme public. Lorsque l'initialisation par défaut est définie comme publique, elle est considérée comme interne. Lorsque l'utilisateur a besoin d'un type public pour être initialisable avec un initialiseur sans argument dans un autre module, fournissez explicitement un initialiseur public sans argument dans le cadre de la définition du type.

Contrôle d'accès pour les protocoles

Lorsque nous définissons un nouveau protocole pour hériter des fonctionnalités d'un protocole existant, les deux doivent être déclarés avec les mêmes niveaux d'accès pour hériter les propriétés de l'autre. Le contrôle d'accès Swift 4 ne permettra pas aux utilisateurs de définir un protocole «public» qui hérite d'un protocole «interne».

public protocol tcpprotocol {
   init(no1: Int)
}
public class mainClass {
   var no1: Int      // local storage
   init(no1: Int) {
      self.no1 = no1 // initialization
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }
   
   // Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

res is: 20
res is: 30
res is: 50

Contrôle d'accès pour les extensions

Swift 4 ne permet pas aux utilisateurs de fournir un modificateur de niveau d'accès explicite pour une extension lorsque l'utilisateur utilise cette extension pour ajouter la conformité de protocole. Le niveau d'accès par défaut pour chaque implémentation d'exigence de protocole dans l'extension est fourni avec son propre niveau d'accès de protocole.

Contrôle d'accès pour les génériques

Les génériques permettent à l'utilisateur de spécifier des niveaux d'accès minimum pour accéder aux contraintes de type sur ses paramètres de type.

public struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Contrôle d'accès pour les alias de type

L'utilisateur peut définir des alias de type pour traiter des types de contrôle d'accès distincts. Le même niveau d'accès ou différents niveaux d'accès peuvent être définis par l'utilisateur. Lorsque l'alias de type est «privé», ses membres associés peuvent être déclarés comme «privé, interne de type public». Lorsque l'alias de type est public, les membres ne peuvent pas être alias en tant que nom «interne» ou «privé»

Tous les alias de type que vous définissez sont traités comme des types distincts aux fins du contrôle d'accès. Un alias de type peut avoir un niveau d'accès inférieur ou égal au niveau d'accès du type qu'il alias. Par exemple, un alias de type privé peut aliaser un type privé, interne ou public, mais un alias de type public ne peut pas aliaser un type interne ou privé.

public protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
   
   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
   C1: Container, C2: Container
   where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
   (someContainer: C1, anotherContainer: C2) -> Bool {
   
   // check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }
   
   // check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
   // all items match, so return true
   return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]

Encodage et décodage rapides

Swift 4 présente un nouveau Codable Protocole, qui vous permet de sérialiser et de désérialiser des types de données personnalisés sans écrire de code spécial - et sans avoir à vous soucier de perdre vos types de valeur.

struct Language: Codable {
   var name: String
   var version: Int
}
let swift = Language(name: "Swift", version: 4)
let java = Language(name: "java", version: 8)
let R = Language(name: "R", version: 3

Notez que Langauage est conforme au protocole codable. Nous allons maintenant le convertir en une représentation de données Json en utilisant une simple ligne.

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(java) {
   //Perform some operations on this value.
}

Swift encodera automatiquement toutes les valeurs de votre type de données.

Vous pouvez décoder les données en utilisant la fonction Decoder comme

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded) {
   //Perform some operations on this value.
}

JSONEncoder et son équivalent de liste de propriétés PropertyListEncoder ont de nombreuses options pour personnaliser leur fonctionnement.