Latest web development tutorials

Swift Zugriffskontrolle

Zugriffskontrolle kann in anderen Quelldateien oder Module von Code zu Code Zugriffsebene definiert werden.

Sie können explizit auf eine einzige Art (Klasse, Struktur Enumeration) Zugriffsebenen zu setzen, auch diese Art von Eigenschaften geben können, Funktionen, Initialisierungsmethode, der Grundtyp, stellen Sie die Index-Indizes Zugriffsebenen.

Abkommen kann auch innerhalb eines bestimmten Bereichs zu verwenden, beschränkt werden, einschließlich der Vereinbarung in der globalen Konstanten, Variablen und Funktionen.

Based Access Control Modul mit den Quelldateien.

Die Module werden durch eine separate Einheit definiert zu bauen und Framework oder Anwendung veröffentlichen. Ein Modul kann in der Swift im Import-Schlüsselwort verwendet werden, stellt ein weiteres Modul.

Die Quelldatei ist eine einzelne Quelldatei, die in der Regel zu einem Modul gehört, das die Quelldateien enthält, kann mehrere Klassen und Funktionen definieren.

Swift bietet drei verschiedene Ebenen der Zugangscode Einheit: public, intern, privat.

Zugriffsebene Begriffsbestimmungen
Öffentlichkeit Jede Einheit, die Ihre Dateien im Quellenmodul zugreifen können, können andere die Quelle zugreifen Dateien aller Einheiten durch die Einführung des Moduls.
intern : Jede Entität, die Ihre Dateien im Quellenmodul zugreifen können, aber andere können die Quellmoduldatei Entitäten nicht darauf zugreifen.
privat Verwenden Sie nur Unternehmen in der aktuellen Quelldatei, als eine private Einrichtung bekannt.

Zugang der Öffentlichkeit zu den am weitesten fortgeschrittenen Niveau, privat ist die unterste Ebene des Zugangs.

Grammatik

Durch Modifikatoren öffentlichen, internen, privaten Zugang Ebene Einheiten erklärt:

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

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

Es sei denn, es spezielle Anweisungen sind, sonst Einheiten verwenden die Standard-Zugriffsebene intern.


Funktion Typ Zugriff

Zugriffsebenen auf Basis von Parametern abgeleitete Funktion erfordert die Art der Rückgabetyp der Funktion und Zugriffsebene.

Das folgende Beispiel definiert eine benannte somefunction globale Funktion, und nicht explizit die Zugriffsebene bestätigen.

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 函数实现
}

Funktion in einer der Zugriffsebene SomeInternalClass Klassen ist intern, der andere SomePrivateClass Zugriffsebene ist privat. Daher wird gemäß dem Prinzip der Zugriffsebene Tupel ist das Tupel Zugriffsebene privat.

Da die Funktion der Typ des Zugriffsebene zurückgibt, ist privat, so dass Sie den privaten Modifikator erklären ausdrücklich die Funktion verwenden müssen:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 函数实现
}

Diese Funktion wird als öffentliche oder interne erklärt, oder verwenden Sie die interne Standardzugriffsebenen sind falsch.


Zugang Aufzählungstyp

Zugriffsebene Enumerationsmember aus der Aufzählung geerbt, können Sie aufzählen nicht die Mitglieder einer gesonderten Erklärung unterschiedliche Zugriffsebenen.

Beispiele

Zum Beispiel wird das folgende Beispiel, die Aufzählung Studenten explizit als öffentlicher Ebene erklärt, dann seine Mitglieder Name Markus Zugriffsebene ist auch der Öffentlichkeit:

public enum Student {
    case Name(String)
    case Mark(Int,Int,Int)
}

var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
case .Name(let studName):
    print("学生名: \(studName).")
case .Mark(let Mark1, let Mark2, let Mark3):
    print("学生成绩: \(Mark1),\(Mark2),\(Mark3)")
}

Die obige Programmausführung Ausgabe ist:

学生成绩: 98,97,95

Subklassen Zugang

Zugriffsebene Unterklasse darf das Niveau des Zugangs der Elternklasse nicht überschreiten. Zum Beispiel ist die Zugriffsebene der Elternklasse intern, die Zugriffsebene der Unterklasse kann nicht als öffentlich deklariert werden.

public class SuperClass {
    private func show() {
        print("超类")
    }
}

// 访问级别不能低于超类 internal > public
internal class SubClass: SuperClass  {
    override internal func show() {
        print("子类")
    }
}

let sup = SuperClass()
sup.show()

let sub = SubClass()
sub.show()

Die obige Programmausführung Ausgabe ist:

超类
子类

Konstanten, Variablen, Eigenschaften, Indexzugriff

Konstanten, Variablen, können Attribute nicht mehr als ihre Art von Zugriffsebenen.

Zum Beispiel definieren Sie eine Ebene von öffentlichem Eigentum, aber es ist die Art der privaten Ebene, die vom Compiler nicht erlaubt ist.

In ähnlicher Weise kann der Index nicht eine höhere Rendite als der Index Art oder Arten von Zugriffsebenen haben.

Wenn die Konstanten, Variablen, Eigenschaften, der Index Index definiert Typ privater Ebene ist, muss sie deutlich das Niveau der Zugang zu privaten festgestellt werden:

private var privateInstance = SomePrivateClass()

Getter und Setter Zugang

Getter und Setter Zugriffsebene Konstanten, Variablen, Eigenschaften geerbt Index Index von der Ebene der Zugang, den sie an die Mitglieder angehören.

Setter Zugriffsebenen kann niedriger als die Zugriffsebene sein Getter entsprechen, so dass Sie die Variablen steuern können, Eigenschaften oder Index Index Lese- und Schreibrechte.

class Samplepgm {
    private var counter: Int = 0{
        willSet(newTotal){
            print("计数器: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("新增加数量 \(counter - oldValue)")
            }
        }
    }
}

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

Die obige Programmausführung Ausgabe ist:

计数器: 100
新增加数量 100
计数器: 800
新增加数量 700

Constructor und Standardkonstruktors Zugang

Initialisierung

Wir können die Initialisierung Verfahren anpassen, um die Zugriffsebene zu erklären, aber es gehört zu der Klasse oder auch höhere Zugriffsebene. Aber notwendig Konstruktor Ausnahme, muss es auf die Ebene und den Zugriff auf das gleiche Niveau ihrer Klasse.

Als eine Funktion oder Methode Parameter, Methode der Initialisierung Parameter Zugriffsebene kann nicht kleiner sein als die Zugriffsebene Initialisierungsmethode.

Die Standard-Initialisierungsmethode

Swift ist eine Struktur, bietet die Klasse eine Standardinitialisierung Methode ohne Parameter, für alle ihre Eigenschaftszuweisung zur Verfügung zu stellen, aber nicht einen bestimmten Wert geben.

Die Standard-Initialisierung Methode gehört zur gleichen Zugriffsrechte und die Art der Zugriffsebene.

Beispiele

Benutze das Stichwort Anweisung erforderlich, bevor der Zugriff () init-Methode in jeder Unterklasse.

class classA {
    required init() {
        var a = 10
        print(a)
    }
}

class classB: classA {
    required init() {
        var b = 30
        print(b)
    }
}

let res = classA()
let show = classB()

Die obige Programmausführung Ausgabe ist:

10
30
10

Zugangsvereinbarung

Wenn Sie eine klare Vereinbarung wollen die Zugriffsebene bestätigt, müssen wir beachten Sie, dass Sie der Vereinbarung sicherstellen möchten, nur in der Zugriffsebene Rolle verwendet wird Sie Domain angegeben.

Wenn Sie einen öffentlichen Zugang Protokoll-Ebene zu definieren, die notwendige Funktion der Vereinbarung zu erreichen, wird sie von der Öffentlichkeit Zugang Ebene zur Verfügung gestellt werden. Dies unterscheidet sich von anderen Arten, wie andere Arten von öffentlichen Zugangsebene, der Ebene der Zugang für die Mitglieder ihrer internen.

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 show = SubClass(no1: 30, no2: 50)

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

Die obige Programmausführung Ausgabe ist:

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

Erweiterter Zugriff

Sie können unter den Bedingungen erlaubt es eine Klasse, Struktur, Aufzählung Expansion. Erweiterte Mitglieder der ursprünglichen Klasse-Mitglieder sollten die gleichen Zugriffsrechte haben. Zum Beispiel, erweitern Sie einen gemeinsamen Typ, dann fügen Sie die neuen Mitglieder sollten die gleichen Mitglieder der ursprünglichen internen Standardzugriffsebene haben.

Alternativ können Sie auch explizit die erweiterte Zugriffsebene (wie zum Beispiel die Nutzung von privaten Erweiterung) in der Verlängerung zu erklären, um alle Mitglieder einen neuen Standard-Zugriffsebene bestätigen. Der neue Standard-Zugriffsstufe kann noch einzelne Mitglied der Zugriffsebene abgedeckt bestätigt werden.


Generic Access

Zugriffsebene generische Typ oder generische Funktionen der gattungs zu nehmen, die Funktion selbst, die generische Typparameter der drei untersten Ebenen des Zugangs.

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

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

tos.push("泛型")
print(tos.items)

tos.push("类型参数")
print(tos.items)

tos.push("类型参数名")
print(tos.items)
let deletetos = tos.pop()

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]

Typ alias

Alles, was Sie Aliase geben wird als eine andere Art definiert werden, um Zugriffskontrolle zu erleichtern. Zugriffsebene eines Typs Alias-Typ kann nicht höher sein als das ursprüngliche Niveau des Zugangs.

Zum Beispiel kann eine private Klasse Typ-Aliasnamen zu einem öffentlichen, internen, privaten Typ zugeordnet werden, aber ein öffentlicher Ebene Typ-Aliasnamen können nur auf einer öffentlichen Ebene Typ eingestellt werden kann, nicht auf interne oder privater Ebene Typ eingestellt werden .

Hinweis: Diese Regel auch für den Fall anwendet, um Protokollkonformität zu dem jeweiligen Typnamen und einem Alias ​​zu erfüllen.

public protocol Container {
    typealias 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)
    }
    
    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("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("Where 语句")
print(tos.items)

var eos = ["Swift", "泛型", "Where 语句"]
print(eos)

Die obige Programmausführung Ausgabe ist:

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "Where 语句"]
["Swift", "泛型", "Where 语句"]