首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Swift 如何使用 Access Control

1.访问控制(Access Control)

访问控制可以限制别的源文件或者模块来访问你的代码。该特性可以让你隐藏代码的具体实现,从而使代码有更好的封装性

2.5 个关键字

对于访问控制,Swift 提供了五个关键字。根据可访问的优先级,从高到低依次为:open、public、internal、fileprivate、private。

下面来总结一下这几个关键字的区别:

open:本模块和其他模块都能访问,只能应用在类或者类成员上。允许其他模块继承或重写。

public:本模块和其他模块都能访问,不允许其他模块继承或重写。

internal:本模块能访问。不写访问控制关键字,默认为 internal。

fileprivate:当前源文件访问。

private:只允许在当前定义体内使用。

关于 public 还有一点值得注意:当使用 public 去修饰一个类型的时候,该类型是 public,但其成员、方法默认是 internal 的。如果你想要使其可以让其他模块调用,必须要显式的用 public 修饰。这样做的目的是防止该类型中 internal 的代码被当做 public 公开。

3. 指导准则

来自官方文档的指导原则:No entity can be defined in terms of another entity that has a lower (more restrictive) access level.

翻译:一个实体不可以被更低访问级别的实体多定义。

代码举例:

如上述代码所示,stu 用public修饰,而 Student 使用fileprivate。这样就导致了 stu 的访问权限比 Student 的,从而造成编译器错误。将 Student 改为 public 或 open 即可消除编译器错误。

代码示例:

虽然 SomePublicClass 为 public,但 someInternalProperty 是 internal ,即别的模块无法调用,只能访问显式 public 的 somePublicProperty。

4. 元组(Tuple)

元组类型的访问控制 ≤ 元组类型中最小的。

因为 fileprivate 小于 internal,所以 ani 只能使用fileprivate或者private修饰,否则会有编译器错误。

5. 泛型

泛型类型的访问控制需 ≤类型访问级别以及所有泛型类型参数的访问级别的最小值。

上述代码,虽然 Person 使用 public 修饰,但 Cat 使用的 fileprivate, fileprivate 小于 public 和 internal。所以 p 的访问权限修饰符只能使用fileprivate或者private修饰,否则会有编译器错误。

6. 成员与嵌套类型

类型的访问控制会影响到成员(属性、方法、构造器、下标)、嵌套类型的访问控制。

一般情况下,类型为 fileprivate 或 private,那么成员和嵌套类型也默认为 fileprivate 或 private。

一般情况下,类型为 internal 或 public,那么成员和嵌套类型默认为 public。

7. 成员的重写

子类重写成员的访问控制须 ≥ 子类,或者 ≥ 父类被重写成员。

父类的成员不能被成员作用域外定义的子类重写。

因为子类中的 age 访问控制为 internal,而父类中的 age 访问控制为 private, internal ≥ private (子类的重写成员访问控制≤ 父类被重写成员,不符合上面的第一条),因此造成编译器错误。将 private 删除即可消除错误。

若不想删除 private 也可做以下修改:

因为 age 的作用域就是 Person 的整个大括号,所以这样符合上面的第二条。

8.Getter、Setter

get/set 的访问控制默认与所属环境一致,即该类型为 private ,则get/set 也为 private。

在日常开发中,我们经常会碰到这样一个问题:允许别人读取该属性的值,但不允许修改。如何实现这个呢?答案就是使用private(set)

age 外部可读但不可写。

9. 构造器

如果别的模块想要调用 public 修饰的类的默认构造器,则需用 public 显式的修饰默认构造器。因为默认构造器是 internal。

如果结构体中有 fileprivate、private的存储属性,那么成员构造器也需预期保持一致。

10. Enum

所有 case 自动与 enum 的访问控制保持一致。

case 不能单独设置访问控制。

CompassPoint 的所有 case 都为 public,不能给他们设置别的访问控制。

11. Protocol

协议中定义的内容自动与类型的访问控制保持一致,不可单独设置访问控制。

大家可以看一下下面的代码是否能编译通过:

答案是不能,因为 public 修饰的 PublishClass,它的 test() 默认是 internal,而 PublicProtocol 的 test() 是 public,所以报错。正确代码如下:

12.Extension

如果显式的设置了 extension 的访问控制,extension 的成员自动接收 extension 的访问控制。

若没有显式设置,则 extension 中的成员与类型中定义的成员访问控制一致。

可以单独给 extension 中的成员设置访问控制。

不能给用于遵守协议的 extension 显式设置 extension 的访问控制。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210131A078L000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券