swift学习笔记之-访问控制
//访问控制
import UIKit
/*访问控制(Access Control)
1.访问控制可以限定其他源文件或模块中的代码对你的代码的访问级别。这个特性可以让我们隐藏代码的一些实现细节,并且可以为其他人可以访问和使用的代码提供接口
2.你可以明确地给单个类型(类、结构体、枚举)设置访问级别,也可以给这些类型的属性、方法、构造器、下标等设置访问级别
3.协议也可以被限定在一定的范围内使用,包括协议里的全局常量、变量和函数
模块:
1.模块指的是独立的代码单元,框架或应用程序会作为一个独立的模块来构建和发布。
2.在 Swift 中,一个模块可以使用 import 关键字导入另外一个模块
3.在 Swift 中,Xcode 的每个 target(例如框架或应用程序)都被当作独立的模块处理。如果你是为了实现某个通用的功能,或者是为了封装一些常用方法而将代码打包成独立的框架,这个框架就是 Swift 中的一个模块。当它被导入到某个应用程序或者其他框架时,框架内容都将属于这个独立的模块
源文件:源文件就是 Swift 中的源代码文件,它通常属于一个模块,即一个应用程序或者框架
访问级别:
1.Swift 为代码中的实体提供了三种不同的访问级别。这些访问级别不仅与源文件中定义的实体相关,同时也与源文件所属的模块相关。
1.public:可以访问同一模块源文件中的任何实体,在模块外也可以通过导入该模块来访问源文件里的所有实体。通常情况下,框架中的某个接口可以被任何人使用时,你可以将其设置为 public 级别。
2.internal:可以访问同一模块源文件中的任何实体,但是不能从模块外访问该模块源文件中的实体。通常情况下,某个接口只在应用程序或框架内部使用时,你可以将其设置为 internal 级别。
3.private:限制实体只能在所在的源文件内部使用。使用 private 级别可以隐藏某些功能的实现细节。
4.public 为最高(限制最少)访问级别,private 为最低(限制最多)访问级别
访问级别基本原则:
1.访问级别遵循一个基本原则:不可以在某个实体中定义访问级别更高的实体
2.默认访问级别:如果你不为代码中的实体显式指定访问级别,那么它们默认为 internal 级别
单 target 应用程序的访问级别:
当你编写一个单 target 应用程序时,应用的所有功能都是为该应用服务,而不需要提供给其他应用或者模块使用,所以我们不需要明确设置访问级别,使用默认的访问级别 internal 即可。但是,你也可以使用 private 级别,用于隐藏一些功能的实现细节。
框架的访问级别:
当你开发框架时,就需要把一些对外的接口定义为 public 级别,以便使用者导入该框架后可以正常使用其功能。这些被你定义为 public 的接口,就是这个框架的 API
单元测试 target 的访问级别:
当你的应用程序包含单元测试 target 时,为了测试,测试模块需要访问应用程序模块中的代码。默认情况下只有 public 级别的实体才可以被其他模块访问。然而,如果在导入应用程序模块的语句前使用 @testable 特性,然后在允许测试的编译设置(Build Options -> Enable Testability)下编译这个应用程序模块,单元测试 target 就可以访问应用程序模块中所有 internal 级别的实体
类型访问级别:
1.一个类型的访问级别也会影响到类型成员(属性、方法、构造器、下标)的默认访问级别。如果你将类型指定为 private 级别,那么该类型的所有成员的默认访问级别也会变成 private
2.一个 public 类型的所有成员的访问级别默认为 internal 级别,而不是 public 级别。如果你想将某个成员指定为 public 级别,那么你必须显式指定
元组类型:元组的访问级别将由元组中访问级别最严格的类型来决定,元组不同于类、结构体、枚举、函数那样有单独的定义。元组的访问级别是在它被使用时自动推断出的,而无法明确指定
函数类型:函数的访问级别根据访问级别最严格的参数类型或返回类型的访问级别来决定。但是,如果这种访问级别不符合函数定义所在环境的默认访问级别,那么就需要明确地指定该函数的访问级别
枚举类型:枚举成员的访问级别和该枚举类型相同,你不能为枚举成员单独指定不同的访问级别,枚举定义中的任何原始值或关联值的类型的访问级别至少不能低于枚举类型的访问级别。例如,你不能在一个 internal 访问级别的枚举中定义 private 级别的原始值类型
嵌套类型:如果在 private 级别的类型中定义嵌套类型,那么该嵌套类型就自动拥有 private 访问级别。如果在 public 或者 internal 级别的类型中定义嵌套类型,那么该嵌套类型自动拥有 internal 访问级别。如果想让嵌套类型拥有 public 访问级别,那么需要明确指定该嵌套类型的访问级别
子类:子类的访问级别不得高于父类的访问级别,可以在符合当前访问级别的条件下重写任意类成员,可以通过重写为继承来的类成员提供更高的访问级别
常量、变量、属性、下标:
1.常量、变量、属性不能拥有比它们的类型更高的访问级别,如果常量、变量、属性、下标的类型是 private 级别的,那么它们必须明确指定访问级别为 private
2.常量、变量、属性、下标的 Getters 和 Setters 的访问级别和它们所属类型的访问级别相同
3.Setter 的访问级别可以低于对应的 Getter 的访问级别,这样就可以控制变量、属性或下标的读写权限。在 var 或 subscript 关键字之前,你可以通过 private(set) 或 internal(set) 为它们的写入权限指定更低的访问级别,存储型属性有默认的Getter和Setter
4.可以在必要时为 Getter 和 Setter 显式指定访问级别
构造器:自定义构造器的访问级别可以低于或等于其所属类型的访问级别。唯一的例外是必要构造器,它的访问级别必须和所属类型的访问级别相同,如同函数或方法的参数,构造器参数的访问级别也不能低于构造器本身的访问级别
默认构造器:默认构造器的访问级别与所属类型的访问级别相同,除非类型的访问级别是 public。如果一个类型被指定为 public 级别,那么默认构造器的访问级别将为 internal。如果你希望一个 public 级别的类型也能在其他模块中使用这种无参数的默认构造器,你只能自己提供一个 public 访问级别的无参数构造器
结构体默认的成员逐一构造器:如果结构体中任意存储型属性的访问级别为 private,那么该结构体默认的成员逐一构造器的访问级别就是 private。否则,这种构造器的访问级别依然是 internal。如同前面提到的默认构造器,如果你希望一个 public 级别的结构体也能在其他模块中使用其默认的成员逐一构造器,你依然只能自己提供一个 public 访问级别的成员逐一构造器
协议:
1.协议中的每一个要求都具有和该协议相同的访问级别。你不能将协议中的要求设置为其他访问级别。这样才能确保该协议的所有要求对于任意采纳者都将可用
2.继承来的协议的访问级别低于或等于父协议的访问级别
3.协议一致性:一个类型可以采纳比自身访问级别低的协议,采纳了协议的类型的访问级别取它本身和所采纳协议两者间最低的访问级别
扩展:
1.可以在访问级别允许的情况下对类、结构体、枚举进行扩展。扩展成员具有和原始类型成员一致的访问级别
2.可以明确指定扩展的访问级别(例如,private extension),从而给该扩展中的所有成员指定一个新的默认访问级别。这个新的默认访问级别仍然可以被单独指定的访问级别所覆盖
泛型:泛型类型或泛型函数的访问级别取决于泛型类型或泛型函数本身的访问级别,还需结合类型参数的类型约束的访问级别,根据这些访问级别中的最低访问级别来确定
类型别名:你定义的任何类型别名都会被当作不同的类型,以便于进行访问控制。类型别名的访问级别不可高于其表示的类型的访问级别
*/
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 类成员
}
//=======
public class A {
private func someMethod() {}
}
internal class B: A {
override internal func someMethod() {} //在符合当前访问级别的条件下,通过重写为继承来的类成员提供更高的访问级别
}
//=======
struct TrackedString {
private(set) var numberOfEdits = 0 //可以在其他的源文件中实例化该结构体并且获取到 numberOfEdits 属性的值,但是你不能对其进行赋值
var value: String = "" {
didSet {
numberOfEdits++
}
}
}
public struct TrackedString1 {
public private(set) var numberOfEdits = 0 //在必要时为Getter和Setter显式指定访问级别,结合 public 和 private(set) 修饰符把结构体中的 numberOfEdits 属性的 Getter 的访问级别设置为 public,而 Setter 的访问级别设置为 private
public var value: String = "" {
didSet {
numberOfEdits++
}
}
public init() {}
}
swift学习笔记之-访问控制的更多相关文章
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- Swift学习笔记(一)搭配环境以及代码运行成功
原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...
- swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习笔记一
最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...
- 记录:swift学习笔记1-2
swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...
随机推荐
- How Do Annotations Work in Java?--转
原文地址:https://dzone.com/articles/how-annotations-work-java Annotations have been a very important par ...
- Spring AOP AspectJ Pointcut Expressions With Examples--转
原文地址:http://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with ...
- [转载]UML类图总结
前言 类图和序列图是UML中最常用的两种Diagram.我将做详细的总结.在许多书中,或者网站中,在介绍一个系统的子系统的设计时,很多时候,都是给出简单的类图来简述构成子系统的类之间的关系.这足以说明 ...
- 别用symbolicatecrash来解析crash Log了
今天突然发现了一个解析iOS crash log的好方法,忍不住来分享一下. 相信每个做iOS开发的TX都应该不会对symbolicatecrash陌生,我们第一次遇到真机上产生的崩溃日志时,在网上搜 ...
- javascript中遇到的字符串对象处理
在javascript中对参数处理: 1 <script> 2 function getParam() 3 { 4 urlInfo=window.location.href; //获取当前 ...
- QT学习笔记4
顶层窗口-MainWindow 新建项目,选择基类的时Base Class是QMainWindow 最上面是Window Title,用于显示标题和控制按钮,比如最大化.最小化和关闭等:下面一些是Me ...
- 从零开始学习jQuery (二) 万能的选择器
本系列文章导航 从零开始学习jQuery (二) 万能的选择器 一.摘要 本章讲解jQuery最重要的选择器部分的知识. 有了jQuery的选择器我们几乎可以获取页面上任意的一个或一组对象, 可以明显 ...
- 检测IP地址的正则表达式
正则表达式: ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) ((2[0-4]\d|25[0-5]|[01]?\d\ ...
- 编写CLR存储过程中使用SqlDataRecord
温习一下这些天学习的CLR编程,存储过程,函数. 编写CLR的存储过程,运行起来的效率,果然比普通的SQL语句,存储过程或是函数均高. 以后专案需求,或是执行效率较高的SQL,得写成CLR程序,再部署 ...
- 优化Angular应用的性能
MVVM框架的性能,其实就取决于几个因素: 监控的个数 数据变更检测与绑定的方式 索引的性能 数据的大小 数据的结构 我们要优化Angular项目的性能,也需要从这几个方面入手. 1. 减少监控值的个 ...