Latest web development tutorials

controle de acesso Swift

O controle de acesso pode ser definido em outros arquivos de origem ou módulos de código para o seu nível de acesso ao código.

Você pode explicitamente a um único tipo (classe, struct, enum) para definir os níveis de acesso, também pode dar a estes tipos de propriedades, funções, método de inicialização, o tipo básico, os índices subscritos definir níveis de acesso.

Acordo também pode ser limitada para uso dentro de um determinado intervalo, incluindo o acordo em constantes globais, variáveis ​​e funções.

módulo de controle de acesso baseado com os arquivos de origem.

Os módulos são definidos por uma unidade separada para construir e publicar Framework ou aplicativo. Um módulo poderá ser utilizado no Swift na expressão de importação introduz um outro módulo.

O arquivo de origem é um único arquivo de origem, que geralmente pertence a um módulo que contém os arquivos de origem pode definir várias classes e funções.

Swift oferece três níveis diferentes de entidade código de acesso: público, interno, privado.

Nível de acesso definições
público Qualquer entidade que pode acessar seus arquivos no módulo fonte, outros podem acessar os arquivos de origem de todas as entidades através da introdução do módulo.
interno : Qualquer entidade que pode acessar seus arquivos no módulo de origem, mas outros não podem acessar as entidades de arquivo do módulo de origem.
privado Use única entidade no arquivo de origem atual, conhecida como uma entidade privada.

o acesso público ao nível mais avançado, privado é o menor nível de acesso.

gramática

Ao declarar modificadores público,, entidades internas nível de acesso privado:

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

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

A menos que haja instruções especiais, caso contrário entidades usar o nível de acesso padrão interno.


Tipo de função de Acesso

Os níveis de acesso com base em parâmetros de função derivados requer o tipo de tipo de retorno da função e nível de acesso.

O exemplo a seguir define uma função global chamada someFunction, e não afirma explicitamente o seu nível de acesso.

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

Função em uma das classes SomeInternalClass nível de acesso é interno, o outro nível de acesso SomePrivateClass é privado. Portanto, de acordo com o princípio da tupla nível de acesso, o nível de acesso tupla é privado.

Porque a função retorna o tipo do nível de acesso é privado, portanto, você deve usar o modificador private declarar explicitamente a função:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 函数实现
}

Esta função é declarada como pública ou interna, ou use o padrão níveis de acesso internos estão errados.


Acesso tipo enumerado

membros de enumeração de nível de acesso herdada da enumeração, você não é possível enumerar os membros de uma declaração separada diferentes níveis de acesso.

Exemplos

Por exemplo, o seguinte exemplo, o estudante enumeração é explicitamente declarado como nível público, então seus membros Nome, nível de acesso de Mark também é público:

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)")
}

A saída de execução de programa acima é:

学生成绩: 98,97,95

acesso subclasses

O nível de acesso subclasse não deve exceder o nível de acesso da classe pai. Por exemplo, o nível de acesso da classe pai é interno, o nível de acesso da subclasse não pode ser declarado como público.

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()

A saída de execução de programa acima é:

超类
子类

Constantes, variáveis, propriedades, acesso de índice

Constantes, variáveis, atributos não pode ter mais do que seu tipo de níveis de acesso.

Por exemplo, você define um nível de propriedade pública, mas é o tipo de nível privado, o que não é permitido pelo compilador.

Da mesma forma, o índice não pode ter um retorno maior do que o tipo de índice ou tipos de níveis de acesso.

Se as constantes, variáveis, propriedades, o tipo de índice subscrito definido é nível privado, que deve ser claramente indicado o nível de acesso para o privado:

private var privateInstance = SomePrivateClass()

Getter e acesso Setter

Getters e constantes Setters nível de acesso, variáveis, propriedades, índice subscrito herdado do nível de acesso a que pertencem os membros.

níveis de acesso Setter pode ser menor do que o nível de acesso Getter correspondente, para que possa controlar as variáveis, propriedades ou índice subscrito permissões de leitura e escrita.

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

A saída de execução de programa acima é:

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

Construtor e construtor padrão de acesso

inicialização

Nós podemos personalizar o método de inicialização para declarar o nível de acesso, mas pertence à classe ou então maior nível de acesso. Mas exceção construtor necessário, deve ter acesso ao nível e acesso ao mesmo nível de sua classe.

Como uma função ou método parâmetros, o método de parâmetros de inicialização de nível de acesso não pode ser menor do que o método de inicialização de nível de acesso.

O método padrão de inicialização

Swift é uma estrutura, a classe fornece um método de inicialização padrão sem parâmetros, por todos os seus bens para fornecer atribuição, mas não dá um valor específico.

O método de inicialização padrão pertence ao mesmo nível de acesso eo tipo de nível de acesso.

Exemplos

Utilizar a palavra-chave declaração exigida antes de método de acesso init () em cada subclasse.

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()

A saída de execução de programa acima é:

10
30
10

Acordo de acesso

Se você quer um acordo claro afirma o nível de acesso, é preciso notar que você quer certificar-se o acordo só é usado na função de nível de acesso que afirmou domínio.

Se você definir um protocolo de nível de acesso público, para alcançar a função necessária do acordo que será fornecido pelo nível de acesso público. Isso é diferente de outros tipos, como outros tipos de nível de acesso público, o nível de acesso para os membros da sua interno.

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)")

A saída de execução de programa acima é:

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

acesso estendida

Você pode, nas condições permitir que a classe, estrutura, expansão enumeração. membros estendidos dos membros da classe originais devem ter o mesmo nível de acesso. Por exemplo, você estende um tipo comum, em seguida, adicionar os novos membros devem ter os mesmos membros do nível de acesso interna original padrão.

Alternativamente, você pode declarar explicitamente o nível prolongado de acesso (como o uso de extensão privada) dentro da extensão a todos os membros afirmar um novo nível de acesso padrão. O novo nível de acesso padrão ainda pode-se afirmar membro individual cobertos pelo nível de acesso.


Acesso genérico

O nível de acesso de tipo genérico ou funções genéricas para tomar o tipo genérico, a própria função, o tipo de parâmetro genérico dos três níveis mais baixos de acesso.

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()

A saída de execução de programa acima é:

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

alias de tipo

Qualquer coisa que você digite aliases será definido como um tipo diferente, a fim de facilitar o controle de acesso. O nível de acesso de um tipo de tipo de alias não pode ser maior do que o nível original de acesso.

Por exemplo, um tipo de classe privada aliases pode ser atribuído a um tipo de público, interno, privado, mas um tipo nível público aliases só pode ser definida como um tipo de nível pública não pode ser definida com o tipo de plano interno ou privado .

Nota: Esta regra também se aplica ao caso, a fim de cumprir o protocolo conformidade com o nome do tipo relevante e um alias.

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)

A saída de execução de programa acima é:

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