要限制对代码块、模块和抽象的访问,可以通过访问控制来完成。类、结构体和枚举可以通过访问控制机制根据其属性、方法、初始值设定项和下标进行访问。协议中的常量、变量和函数通过访问控制受到限制,允许全局和本地访问。应用于属性、类型和函数的访问控制可以称为“实体”。
访问控制模型基于模块和源文件。
模块被定义为代码分发的单个单元,可以使用关键字“import”导入。源文件被定义为可以访问多种类型和函数的模块内的单个源代码文件。
Swift 4 语言提供三种不同的访问级别。它们是公共、内部和私人访问权限。
www.sychzs.cn | 访问级别和定义 |
---|---|
1 |
公共 允许使用来自其定义模块的任何源文件(来自导入定义模块的另一个模块的源文件)处理实体。 |
2 |
内部 允许实体在其定义模块的任何源文件中使用,但不能在该模块外部的任何源文件中使用。 |
3 |
私人 将实体的使用限制为其自己的定义源文件。私有访问起着隐藏特定代码功能的实现细节的作用。 |
公共类 SomePublicClass {}
内部类 SomeInternalClass {}
私有类 SomePrivateClass {}
公共变量 somePublicVariable = 0
内部让 someInternalConstant = 0
私有函数 somePrivateFunction() {}
某些函数可能在函数内部声明了没有任何返回值的函数。以下程序将 a 和 b 声明为 sum() 函数。在函数本身内部,通过调用 sum() 传递参数 a 和 b 的值并打印它们的值来消除返回值。要将函数的返回类型设置为私有,请使用 private 修饰符来声明函数的整体访问级别。
private func sum(a: Int, b: Int) {
令 a = a + b
设 b = a - b
打印(a,b)
}
总和(a:20,b:10)
总和(a:40,b:10)
总和(a:24,b:6)
当我们使用游乐场运行上述程序时,我们得到以下结果 -
30 20
50 40
30 24
公共枚举学生{
案例名称(字符串)
案例标记(Int,Int,Int)
}
var StudDetails = www.sychzs.cn("Swift 4")
var StudMarks = Student.Mark(98,97,95)
开关螺柱标记 {
案例.名称(让螺柱名称):
print("学生姓名是:\(studName)。")case .Mark(让Mark1,让Mark2,让Mark3):
print("学生成绩为:\(Mark1),\(Mark2),\(Mark3)。")
}
当我们使用游乐场运行上述程序时,我们得到以下结果 -
学生分数为:98,97,95
Swift 4 语言枚举会自动为枚举的个别情况获得相同的访问级别。考虑访问学生姓名的示例,枚举了三个主题中受保护的标签,枚举名称声明为student,枚举类中存在的成员是属于字符串数据类型的名称,并且标签分别代表Mark1、mark2和mark3,数据类型为Integer。访问学生姓名或分配给他们的成绩。现在,如果执行大小写切换框,则将打印学生姓名,否则将打印学生保护标记。如果两个条件都失败,则将执行默认块。
Swift 4 允许用户对可在当前访问上下文中访问的任何类进行子类化。子类不能具有比其父类更高的访问级别。禁止用户编写内部超类的公共子类。
公开课板球{
内部函数 printIt() {
print("欢迎来到 Swift 4 超级课程")
}
}
内部课程网球:板球{
覆盖内部函数 printIt() {
print("欢迎来到 Swift 4 子类")
}
}
让 cricinstance = 板球()
cricinstance.printIt()
让网球实例 = 网球()
网球实例.printIt()
当我们使用游乐场运行上述程序时,我们得到以下结果 -
欢迎来到Swift超级班
欢迎来到 Swift 子类
Swift 4 常量、变量或属性不能定义为公共类型。用私有类型编写公共属性是无效的。同样,下标不能比其索引或返回类型更公开。
当常量、变量、属性或下标使用私有类型时,常量、变量、属性或下标也必须标记为私有 -
private var privateInstance = SomePrivateClass()
常量、变量、属性和下标的 getter 和 setter 将自动获得与其所属常量、变量、属性或下标相同的访问级别。
类 Samplepgm {
变量计数器:Int = 0{
willSet(newTotal) {
print("总计数器是:\(newTotal)")
}
没有设置{
如果计数器 > 旧值 {
print("新增计数器\(counter - oldValue)")
}
}
}
}
让 NewCounter = Samplepgm()
NewCounter.counter = 100
新计数器.counter = 800
当我们使用游乐场运行上述程序时,我们得到以下结果 -
总计数器为:100
新增柜台100
总计数器为:800
新增柜台700
可以为自定义初始化程序分配小于或等于其初始化类型的访问级别。所需的初始值设定项必须与它们所属的类具有相同的访问级别。初始化程序的参数类型不能比初始化程序自己的访问级别更私有。
声明initialize‘required’关键字的每个子类都需要在init()函数之前定义。
类A类{
必需的 init() {
令 a = 10
打印(一)
}
}
B 类:A 类 {
必需的 init() {
设 b = 30
打印(b)
}
}
让 res = classA()
让 print = classB()
当我们使用游乐场运行上述程序时,我们得到以下结果 -
10
30
10
默认初始化程序与其初始化的类型具有相同的访问级别,除非该类型被定义为公共。当默认初始值设定项定义为公共时,它被视为内部的。当用户需要使用另一个模块的无参数初始值设定项来初始化公共类型时,请显式提供公共无参数初始值设定项作为类型定义的一部分。
当我们定义一个新协议来继承现有协议的功能时,必须使用相同的访问级别声明两者才能继承彼此的属性。 Swift 4 访问控制不允许用户定义继承自“内部”协议的“公共”协议。
公共协议 tcpprotocol {
初始化(no1: Int)
}
公共类主类{
var no1: Int // 本地存储
初始化(no1:整数){
www.sychzs.cn1 = no1 // 初始化
}
}
类子类:mainClass,tcpprotocol {
var no2: 整数init(no1: Int, no2: Int) {
www.sychzs.cn2 = no2
super.init(no1:no1)
}
//只需要一个参数即可方便的方法
需要覆盖方便 init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
让 res = mainClass(no1: 20)
让 print = subClass(no1: 30, no2: 50)
print("res 是:\(www.sychzs.cn1)")
print("res 是:\(www.sychzs.cn1)")
print("res 是:\(www.sychzs.cn2)")
当我们使用游乐场运行上述程序时,我们得到以下结果 -
分辨率为:20
分辨率为:30
分辨率为:50
当用户使用扩展来添加协议一致性时,Swift 4 不允许用户为扩展提供显式访问级别修饰符。扩展中为每个协议要求实现的默认访问级别都有其自己的协议访问级别。
泛型允许用户指定对其类型参数进行类型约束的最低访问级别。
公共结构 TOS {
var 项目 = [T]()
变异 func Push(item: T) {
项目.追加(项目)
}
变异 func pop() -> T {
返回 items.removeLast()
}
}
var tos = TOS()
tos.push(项目:“Swift 4”)
打印(tos.items)tos.push(项目:“泛型”)
打印(tos.items)
tos.push(item: "类型参数")
打印(tos.items)
tos.push(item: "命名类型参数")
打印(tos.items)
让deletetos = tos.pop()
当我们使用游乐场运行上述程序时,我们得到以下结果 -
[斯威夫特 4]
[Swift 4,泛型]
[Swift 4、泛型、类型参数]
[Swift 4、泛型、类型参数、命名类型参数]
用户可以定义类型别名来处理不同的访问控制类型。用户可以定义相同的访问级别或不同的访问级别。当一个类型被别名为“私有”时,它的关联成员可以被声明为“私有、公共类型内部”。当类型被别名为公共时,成员不能被别名为“内部”或“私有”名称
出于访问控制目的,您定义的任何类型别名都将被视为不同的类型。类型别名的访问级别可以小于或等于其别名的访问级别。例如,私有类型别名可以为私有、内部或公共类型添加别名,但公共类型别名不能为内部或私有类型添加别名。
公共协议容器{
关联类型项目类型
变异函数追加(项目:项目类型)
var 计数: Int { get }
下标(i: Int) -> ItemType { get }
}
结构体Stack:容器{
// 原始 Stack 实现
var 项目 = [T]()
变异 func Push(item: T) {项目.追加(项目)
}
变异 func pop() -> T {
返回 items.removeLast()
}
// 遵守Container协议
变异 func 追加(项目:T){
self.push(项目:项目)
}
var 计数: Int {
返回项目.count
}
下标(i: Int) -> T {
退回物品[i]
}
}
func allItemsMatch<
C1:集装箱,C2:集装箱
其中 C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// 检查两个容器是否包含相同数量的项目
if someContainer.count != anotherContainer.count {
返回错误
}
// 检查每对项目,看看它们是否相等
对于 0 中的 i..()
tos.push(项目:“Swift 4”)
打印(tos.items)
tos.push(项目:“泛型”)
打印(tos.items)
tos.push(item: "Where 子句")
打印(tos.items)
var eos = ["Swift 4", "泛型", "Where 子句"]打印(eos)
当我们使用游乐场运行上述程序时,我们得到以下结果 -
[斯威夫特 4]
[Swift 4,泛型]
[Swift 4、泛型、Where 子句]
[Swift 4、泛型、Where 子句]
Swift 4 引入了新的 Codable 协议,该协议允许您序列化和反序列化自定义数据类型,而无需编写任何特殊代码,并且无需担心丢失值类型。
结构语言:可编码{
变量名称:字符串
变量版本:Int
}
让 swift = 语言(名称:“Swift”,版本:4)
让 java = 语言(名称:“java”,版本:8)
让 R = 语言(名称:“R”,版本:3
请注意,语言符合 Codable 协议。现在我们将使用简单的一行将其转换为 Json 数据表示形式。
让编码器 = JSONEncoder()
如果让编码=尝试?编码器.encode(java) {
//对这个值进行一些操作。
}
Swift 会自动对数据类型内的所有值进行编码。
您可以使用解码器功能对数据进行解码,例如
让解码器 = JSONDecoder()
如果让解码=尝试? detector.decode(Language.self, from:encoded) {
//对这个值进行一些操作。
}
JSONEncoder 及其属性列表对应项 PropertyListEncoder 都有许多用于自定义其工作方式的选项。