Swift(二十四、访问权限)


1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~

2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。


二十四、访问权限


这部分的内容有点绕,感觉一下子记住也不现实,只是有个大概的思路,基本的记住,用到去查,以后用熟了可能会好些


限定其他源文件或模块中代码对你的代码的访问级别


1、模块和源文件

模块:以独立单元构建和发布的FrameworkApplication。一个模块可以使用import引入另一个模块

源文件:Swift中的Swift file,编写源代码的文件,通常属于一个模块。


2、访问级别

2.1、三个级别:由高到低

public:可以访问当前模块中源文件里的任何实体。别人引入当前模块也能访问。当想让framework中的某个接口被任何人使用时,设为public级别

internal:可以访问当前模块中源文件里的任何实体。但别人引入当前模块不能访问。某个接口或framework作为内部结构使用时,设为internal

private:只能在当前源文件中使用的实体,称为私有实体。常用来隐藏某些功能的而实现细节

因此Swift中的private区别于其他语言,只要在同一源文件下,一个类可以访问该类定义的所有private实体


2.2、使用原则

使用原则:访问级别统一性
一个public访问级别的变量,不能将其定义为internalprivate—->这句话很拗口,是不能重新定义的意思么?
函数的访问级别不能高于它的参数、返回值类型


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访问级别

嵌套类型定义为:publicinternal,该嵌套类型自动拥有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

GetterSetter的访问级别继承自他们所属成员的访问级别

Setter的级别可以低于Getter,这样就可以控制变量、属性或下标索引的读写权限。可以在varsubscript定义作用于之前,通过private(set)internal(set)先为他们的写权限申明一个较低的级别。
————>此规定只适用于存储属性或计算属性,即使不明确的申明存储属性的settergetterSwift也会隐式地创建,对其进行读取操作,同时也通过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、类型别名

任何定义的类型别名都会被当做不同的类型,以便于进行访问控制

因此一个类型别名的访问级别不可高于原类型的访问级别

以上规则也适用于满足协议一致性而给相关类型命名别名的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值