访问控制 Access Control
访问级别
open 允许在定义实体的模块 其他模块中访问 允许其他模块继承 重写(只能用于类 类成员)
public 允许在定义实体的模块 其他模块中访问 不允许其他模块继承 重写
internal 只允许在定义实体的模块访问 不允许其他模块中访问
fileprivate 只允许在定义实体的源文件中访问
private 只允许在定义实体的封闭声明中访问
实体是被访问级别修饰的内容
绝大部分实体都是internal 修饰的
访问级别的使用准则
一个实体不可以被更低访问级别的实体定义
a.变量/常量类型 >= 变量/常量
b.参数类型 返回值类型 >= 函数
c.父类 >= 子类
d.父协议 >= 子协议
e.原类型 >= typealias
f.原始值类型 关联值类型 >= 枚举类型
g.定义类型A用到的其他类型 >= 类型A
元祖类型访问级别
元祖类型的访问级别是所有成员类型最低的那个
泛型类型的访问级别
泛型类型的访问级别是类型的访问级别 以及 所有泛型类型参数的访问级别中最低的那个
成员 嵌套类型访问级别
类型访问级别会影响成员(属性 方法 初始化器 下标) 嵌套类型的默认访问级别
一般情况下 类型为private 或 filePrivate 那么成员/嵌套类型也是private 或 filePrivate
fileprivate class Person {
var age = 0
func run() {}
enum Season {
case spring,summer
}
}
一般情况下 类型为internal 或 public 那么成员/嵌套类型是internal
private class Person {
}
fileprivate class student: Person {
}
子类重写的成员访问级别 >= 父类的成员访问级别
直接在全局作用域下定义的private相当于filePrivate 那么里面包含的就相当于filePrivate 修饰
getter setter 访问级别
getter setter 默认自动接收他们所属环境的访问级别
可以给setter单独设置一个比getter更低的访问级别 用于限制写的权限
fileprivate(set) public var num = 10
class Person {
private(set) var age = 0
fileprivate(set) public var weight: Int {
set{}
get{
return 10
}
}
internal(set) public subscript(index: Int) -> Int {
set{}
get{
return index
}
}
}
初始化器
如果一个public类想在另一个模块调用编译生成的默认无参初始化器 必须显示提供public的无参初始化器
- 因为public类的默认初始化器是internal级别
requirder初始化器必须要跟他所属类拥有相同的访问级别
如果结构体有为private 或 filePrivate的存储实例属性 那么他的成员初始化器是为private 或 filePrivate
枚举类型的case访问级别
不能给enum的每个case单独设置访问级别
每个case自动接收enum的访问级别
public修饰enum 定义的case也是public
协议的访问级别
协议中定义的要求自动接收协议的访问级别 不能单独设置访问级别
public协议定义的要求也是public
协议实现的访问级别必须 >= 类型的访问级别 或者 >= 协议的访问级别
扩展的访问级别
- 如果有显示设置扩展的访问级别 扩展中添加的成员自动接受扩展的访问级别
- 如果没有显示设置扩展的访问级别 扩展中添加的成员的默认的访问级别 跟直接在类型中定义的成员一样
- 可以单独给扩展添加的成员设置访问级别
- 不能给用于遵守协议的扩展显示的设置扩展的访问级别
- 在同一文件中的扩展 可以写成类似多个部分的类型声明
a.在原本的声明中声明一个私有成员 可以在同一文件的扩展中访问它
b.在扩展中声明一个私有成员 可以在同一文件的其他扩展中 原本声明中访问它
public class Person {
private func run0(){}
private func eat0(){
run1()
}
}
extension Person {
private func run1(){}
private func eat1() {
run0()
}
}
extension Person {
private func eat2() {
run1()
}
}
将方法赋值给var/let
方法可以像函数那样 赋值给let或者var
struct Person {
var age: Int
func run(_ v: Int) {
print("fun run",age,v)
}
}
var p = Person(age: 10)
p.run(20)
var fn = Person.run
var fn2 = fn(Person(age: 10))
fn2(20)
struct Person {
var age: Int
func run(_ v: Int) {
print("fun run",age,v)
}
static func run(_ v: Int) {
print("static run",v)
}
}
var fn = Person.run
fn(20)
struct Person {
var age: Int
func run(_ v: Int) {
print("fun run",age,v)
}
static func run(_ v: Int) {
print("static run",v)
}
}
var fn:((Person) -> (Int) ->()) = Person.run
fn(Person(age: 10))(20)
网友评论