目录
访问控制
/**
模块:指的是独立的代码单元,框架或应用程序会作为一个独立的模块来构建和发布。在 Swift 中,一个模块可以使用 import 关键字导入另外一个模块
在访问权限控制这块,Swift提供了5个不同的访问级别(以下是从高到低排列, 实体指被访问级别修饰的内容)
open:允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写(open只能用在类、类成员上)
public:允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写
internal:只允许在定义实体的模块中访问,不允许在其他模块中访问
fileprivate:只允许在定义实体的源文件中访问
private:只允许在定义实体的封闭声明中访问
绝大部分实体默认都是internal 级别
*/
open class accessClass{} //所有模块可访问 可继承可重写
public class accessClass1{} //所有模块可访问 其它模块不可继承不可重写
internal class accessClass2{} //只有本模块可访问
fileprivate class accessClass3{}//只有当前文件可访问
private class accessClass4{} //只有当前作用域可访问 当其位于文件的全局作用域时 与 filePrivate 相同
/**
一个实体不可以被更低访问级别的实体定义,比如
参数类型、返回值类型 ≥ 函数
父类 ≥ 子类
父协议 ≥ 子协议
原类型 ≥ typealias
原始值类型、关联值类型 ≥ 枚举类型
定义类型A时用到的其他类型 ≥ 类型A
......
*/
//1、变量\常量类型 ≥ 变量\常量
let openvar = accessClass() //常量openvar为internal 类型accessClass为open
let openvar1 = accessClass1() //常量openvar为internal 类型accessClass为public
let openvar2 = accessClass2() //常量openvar为internal 类型accessClass为internal
//let openvar3 = accessClass3() //编译报错 openvar3权限为internal accessClass3权限为 fileprivarte
//let openvar4 = accessClass4() //编译报错 openvar4权限为internal accessClass4权限为 privarte
//2、元祖的访问控制权限
/*元组类型的访问级别是所有成员类型中最低的那个*/
internal struct ACCDog { }
fileprivate class ACCPerson { }
//(ACCDog, ACCPerson) 的访问级别是 fileprivate
fileprivate var data1: (ACCDog, ACCPerson) = (ACCDog(),ACCPerson())
private var data2: (ACCDog, ACCPerson) = (ACCDog(),ACCPerson())
//3、泛型类型
/**泛型类型的访问级别是 类型的访问级别 以及 所有泛型类型参数的访问级别 中最低的那个*/
internal class ACCCar3 {}
fileprivate class ACCDog3 {}
public class ACCPerson3<T1, T2> {}
// ACCPerson3<ACCCar3, ACCDog3>的访问级别是fileprivate
fileprivate var p = ACCPerson3<ACCCar3, ACCDog3>()
//4、成员、嵌套类型
/**
类型的访问级别会影响成员(属性、方法、初始化器、下标)、嵌套类型的默认访问级别
一般情况下,类型为fileprivate或private,那么成员\嵌套类型默认也是fileprivate或private
一般情况下,类型为public或internal,那么成员\嵌套类型默认是internal
*/
public class PublicClass { // public
public var p1 = 0 // public
var p2 = 0 // internal
fileprivate func f1() {} // fileprivate
private func f2() {} // private
}
class InternalClass { // internal
var p = 0 // internal
fileprivate func f1() {} // fileprivate
private func f2() {} // private
}
fileprivate class FilePrivateClass { // fileprivate
func f1() {} // fileprivate
private func f2() {} // private
}
private class PrivateClass { // private
func f() {} // private
}
//5、成员的重写
/**
子类重写成员的访问级别必须 ≥ 子类的访问级别,或者 ≥ 父类被重写成员的访问级别
父类的成员不能被成员作用域外定义的子类重写
*/
public class ACCPerson5 {
//父类的成员不能被成员作用域外定义的子类重写
private var age: Int = 0
fileprivate var height:Int = 180
public class ACCStudent5 : ACCPerson5 {
override var age: Int { //internal
set {}
get {10}
}
}
}
public class ACCStudent5 : ACCPerson5 {
// override var age : Int{
var age : Int{
set {}
get {10}
}
override var height: Int{
set{}
get{180}
}
}
func ACCPerson5Test() -> Void {
let stu = ACCPerson5.ACCStudent5()
print("stu.age = ",stu.age)
}
//6、下面代码能否编译通过
/**
直接在全局作用域下定义的private等价于fileprivate
*/
//6_0可以编译通过
private class ACCPerson6 {}
fileprivate class ACCStudent6:ACCPerson {}
//6_1可以编译通过
private struct ACCDog61 {
var age: Int = 0
func run() {}
}
fileprivate struct ACCPerson61 {
var dog: ACCDog61 = ACCDog61()
mutating func walk() {
dog.run()
dog.age = 1
}
}
//6_2不可以编译通过
private struct ACCDog62 {
private var age: Int = 0
private func run() {}
}
fileprivate struct ACCPerson62 {
var dog: ACCDog62 = ACCDog62()
mutating func walk() {
// dog.run() //无法访问'run' is inaccessible due to 'private' protection level
// dog.age = 1 //无法访问'age' is inaccessible due to 'private' protection level
}
}
//7、getter、setter
/**
getter、setter默认自动接收它们所属环境的访问级别
可以给setter单独设置一个比getter更低的访问级别,用以限制写的权限
*/
fileprivate(set) public var num = 10
class ACCPerson7 {
private(set) var age = 0
fileprivate(set) public var weight: Int {
set {}
get { 10 }
}
internal(set) public subscript(index: Int) -> Int {
set {}
get { index }
}
}
//8、初始化器
/**
如果一个public类想在另一个模块调用编译生成的默认无参初始化器,必须显式提供public的无参初始化器
因为public类的默认初始化器是internal级别
required初始化器 ≥ 它的默认访问级别
如果结构体有private\fileprivate的存储实例属性,那么它的成员初始化器也是private\fileprivate
否则默认就是internal
*/
//9、枚举类型的case
/*
不能给enum的每个case单独设置访问级别
每个case自动接收enum的访问级别
public enum定义的case也是public
*/
//10、协议
/*
协议中定义的要求自动接收协议的访问级别,不能单独设置访问级别
public协议定义的要求也是public
协议实现的访问级别必须 ≥ 类型的访问级别,或者 ≥ 协议的访问级别
下面代码能编译通过么?
*/
//public protocol ACCRunnable10 {
// func run()
//}
//
//public class ACCPerson10 : ACCRunnable10 {
// func run() {}
//}
//11、扩展
/*
如果有显式设置扩展的访问级别,扩展添加的成员自动接收扩展的访问级别
如果没有显式设置扩展的访问级别,扩展添加的成员的默认访问级别,跟直接在类型中定义的成员一样
可以单独给扩展添加的成员设置访问级别
不能给用于遵守协议的扩展显式设置扩展的访问级别
在同一文件中的扩展,可以写成类似多个部分的类型声明
在原本的声明中声明一个私有成员,可以在同一文件的扩展中访问它
在扩展中声明一个私有成员,可以在同一文件的其他扩展中、原本声明中访问它
*/
public class ACCPerson11 {
private func run0() {}
private func eat0() {
run1()
}
}
extension ACCPerson11 {
private func run1() {}
private func eat1() {
run0()
}
}
extension ACCPerson11 {
private func eat2() {
run1()
}
}
将方法赋值给let/var
//二、将方法赋值给let/var
func fnSet() -> Void {
//方法也可以像函数那样,赋值给一个let或者var
struct Person {
var age: Int = 0
func run(_ v: Int) {
print("func run", age, v,self)
}
static func run(_ v: Int) {
print("static func run", v,self)
}
}
let fn1 = Person.run
fn1(10) // static func run 10 Person
let fn2: (Int) -> () = Person.run
fn2(20) // static func run 20 Person
let fn3: (Person) -> ((Int) -> ()) = Person.run
fn3(Person(age: 18))(30) // func run 18 30 Person(age: 18)
let per = Person()
let objfn = per.run
objfn(40)// func run 0 40 Person(age: 0)
}
行者常至,为者常成!