1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~
2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。
二十四、访问权限
这部分的内容有点绕,感觉一下子记住也不现实,只是有个大概的思路,基本的记住,用到去查,以后用熟了可能会好些
1、模块和源文件
模块:以独立单元构建和发布的Framework
活Application
。一个模块可以使用import
引入另一个模块
源文件:Swift
中的Swift file
,编写源代码的文件,通常属于一个模块。
2、访问级别
2.1、三个级别:由高到低
public
:可以访问当前模块中源文件里的任何实体。别人引入当前模块也能访问。当想让framework
中的某个接口被任何人使用时,设为public
级别
internal
:可以访问当前模块中源文件里的任何实体。但别人引入当前模块不能访问。某个接口或framework
作为内部结构使用时,设为internal
private
:只能在当前源文件中使用的实体,称为私有实体。常用来隐藏某些功能的而实现细节
因此Swift
中的private
区别于其他语言,只要在同一源文件下,一个类可以访问该类定义的所有private
实体
2.2、使用原则
使用原则:访问级别统一性
一个public
访问级别的变量,不能将其定义为internal
和private
—->这句话很拗口,是不能重新定义的意思么?
函数的访问级别不能高于它的参数、返回值类型
2.3、默认访问级别
默认为internal
3、自定义类型
类的访问级别会影响类成员(属性,函数,构造方法等)的默认级别。
注意即使这个类是public
级别,但是它的成员默认为internal
级别,而不是public
public class SomePublicClass { // 显式的 public 类
public var somePublicProperty = 0 // 显式的 public 类成员
var someInternalProperty = 0 // 隐式的 internal 类成员
private func somePrivateMethod() {} // 显式的 private 类成员
}
class SomeInternalClass { // 隐式的 internal 类
var someInternalProperty = 0 // 隐式的 internal 类成员
private func somePrivateMethod() {} // 显式的 private 类成员
}
private class SomePrivateClass { // 显式的 private 类
var somePrivateProperty = 0 // 隐式的 private 类成员
func somePrivateMethod() {} // 隐式的 private 类成员
}
3.1、元组类型
可构建一个包含两种不同类型元素的元组,访问级别也可不同。
元组的访问级别与元组中访问级别最低的类型一致
3.2、函数类型
函数的访问级别需要根据函数的参数类型和返回值类型的访问级别得出,也是跟最低级别一致
例如下列函数:
private func someFunction() -> (SomeInternalClass,SomePrivateClass) {
// function implementation goes here
}
返回值为元组,级别是private
,那么函数也是private
,必须要用private
申明,而不能默认为internal
级别,或者申明为public
3.3、枚举类型
枚举的成员访问级别继承自该枚举,不能为枚举中那个的成员单独申明不同的访问级别
3.4、原始值和关联值
枚举中定义的原始值和关联值必须有一个访问级别,且不能低于枚举的访问级别
3.5、嵌套类型
嵌套类型定义为:private
,该嵌套类型自动获得private
访问级别
嵌套类型定义为:public
或internal
,该嵌套类型自动拥有internal
访问级别,如果想让其有public
访问级别,需要显式声明
3.6、子类
子类的访问级别不能高于父类的访问级别
同时还满足各访问级别作用于的前提下,可以重写任意类成员(方法,属性,初始化方法,下标索引等)。即使是private
也能重写,子类还能访问父类成员
public class A {
private func someMethod() {}
}
internal class B: A {
override internal func someMethod() {
super.someMethod()
}
}
3.7、常量、变量、属性、下标
常量、变量、属性不能拥有比他们的类型更高的访问级别
3.8、Getter和Setter
Getter
和Setter
的访问级别继承自他们所属成员的访问级别
Setter
的级别可以低于Getter
,这样就可以控制变量、属性或下标索引的读写权限。可以在var
或subscript
定义作用于之前,通过private(set)
或internal(set)
先为他们的写权限申明一个较低的级别。
————>此规定只适用于存储属性或计算属性,即使不明确的申明存储属性的setter
和getter
,Swift
也会隐式地创建,对其进行读取操作,同时也通过private(set)
或internal(set)
设置访问级别
实例
struct TrackedString {
private(set) var numberOfEdits = 0
var value:String = "" {
didSet {
numberOfEdits++
}
}
}
存储String
的属性value
,初始值为空,同时定义numberOfEdits
来记录属性value
被修改的次数。
结构体和value
都没有显式地申明访问级别,默认拥有的访问级别internal
。但是numberOfEdits
使用private(set)
进行声明,表示该属性只能在定义该结构体的源文件中赋值。但是它的getter是internal级别的。说明numberOfEdits
只在当前源文件可读写,而在源文件所属模块中只是可读属性
var stringToEdit = TrackedString()
stringToEdit.value = "A"
stringToEdit.value += "+B"
stringToEdit.value += "+C"
stringToEdit.value += "+D"
print("The number of edits is \(stringToEdit.numberOfEdits)")
Output:
The number of edits is 4
4、初始化
4.1、初始化
初始化方法可申明级别,但不能高于所属类的访问级别
必要构造器级别必须和所属类的访问级别一样
4.2、默认初始化方法
默认初始化方法的访问级别与所属类型的访问级别相同,但是最高级别为internal
但是注意:如果一个类是public
,那么默认初始化的访问级别为internal
。如果想让无参的默认初始化在其他模块中被使用,那么必须提供public
级别的无参数初始化方法
4.3、结构体的默认成员初始化方法
只要结构体中任一存储属性的级别为private
,那么默认成员初始化方法级别为private
尽管如此,结构体的初始化方法的访问级别依然是internal
5、协议
5.1、协议
为协议申明级别,需要注意确保协议旨在申明的访问级别作用域中使用
协议中每个必须要实现的函数都跟协议相同的访问级别
区别于其他类型,public
级别的协议,实现函数也是public
的访问级别。其他的类型public
访问级别,他们的成员都是internal
的!!!!
5.2、协议继承
继承的协议最高只能和被继承协议的访问级别相同
5.3、协议一致性
类的访问级别取决于它本身和所采用协议中最低的访问级别
高级别类可以采用比自己级别低得协议,但是这个类自身的访问级别也会降级
6、扩展
6.1、扩展
扩展成员具有和原始类成员一致访问级别
或者可以明确申明扩展的访问级别(比如用private extension
)给扩展内所有成员申请一个新的默认访问级别。新的默认访问级别仍可以被单独成员所申明的访问级别所覆盖
6.2、协议的扩展
扩展协议遵循该协议的访问级别
7、泛型
取决于泛型类型、函数本身、泛型类型参数三者中的最低访问级别
8、类型别名
任何定义的类型别名都会被当做不同的类型,以便于进行访问控制
因此一个类型别名的访问级别不可高于原类型的访问级别
以上规则也适用于满足协议一致性而给相关类型命名别名的情况