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 语句"]