iOS学习笔记49-Swift(九)访问控制
一、Swift的访问控制
Swift
中的访问控制模型基于模块和源文件这两个概念
- 模块
指的是Framework
或App bundle
。在Swift
中,可以用import
关键字引入自己的工程。 - 源文件
指的是Swift
中的Swift File
,就是编写Swift
代码的文件,它通常是属于某一个模块。
Swift提供了三种不同的访问级别:
Public
:【使用public
修饰】【范围大】
可以访问当前模块及其他模块中的任何实体(通常用于Framework
)Internal
:【使用internal
修饰】【范围中】
可以访问当前模块中的任何实体,但是在模块外无法访问,这是所有实体的默认访问级别(通常在一个单目标Application
中不需要自行设置访问级别)Private
:【使用private
修饰】【范围小】
只能访问当前源文件中的实体,用作隐藏某些功能的实现细节
访问级别从低到高:Private
< Internal
< Public
访问控制的使用规则挺多的,我这里进行了概括:
- 【成员(属性和方法) <= 类】
- 【(常量、变量、属性、下标脚本) <= 类型】
- 【Setter <= Getter】
- 【required方法 == 类】【默认逐一构造函数 <= 所有成员】
- 【子类 <= 父类】【子协议 <= 父协议】
- 子类重写父类成员修改访问范围
- 【协议成员 == 协议】【类 >= 协议】【协议实现 >= 协议要求】
- 【元组 = Min(所有元素类型)】
- 【函数 = Min(参数类型,返回值类型)】
- 【枚举成员 == 枚举】【(原始值,关联值) >= 枚举】
- 【泛型类型 = Min(类类型,泛型参数)】
- 【类型别名 <= 原类型】
二、访问控制使用规则详解
1.【成员(属性和方法) <= 类】
/*
1.【成员(属性和方法) <= 类】
如果你将类申明为private类,那么该类的所有成员的默认访问级别也会成为private
如果你将类申明为public或者internal类,那么该类的所有成员默认访问级别是internal。
*/
public class SomePublicClass { // 显示的public类
public var somePublicProperty = 0 // 显示的public类成员
var someInternalProperty = 0 // 隐式的internal类成员
internal var someInternalProperty2 = 0 //显示的internal类成员
private func somePrivateMethod() {} // 显示的private类成员
}
internal class SomeInternalClass { // 显示的internal类
var someInternalProperty = 0 // 隐式的internal类成员
private func somePrivateMethod() {} // 显示的private类成员
//Error:-> public var somePublicProperty = 0
}
private class SomePrivateClass { // 显示的private类
var somePrivateProperty = 0 // 隐式的private类成员
func somePrivateMethod() {} // 隐式的private类成员
//Error:-> public var somePublicProperty = 0
//Error:-> internal var someInternalProperty = 0
}
2.【(常量、变量、属性、下标脚本) <= 类型】
/* 2.【(常量、变量、属性、下标脚本) <= 自己类型】 */
private let somePrivate1 = SomePrivateClass() //变量为private <= 类型为private
private let somePrivate2 = SomeInternalClass()//变量为private <= 类型为internal
private let somePrivate3 = SomePublicClass()//变量为private <= 类型为public
//Error:internal let someInternal1 = SomePrivateClass() //变量internal大于类型private,错误
internal let someInternal2 = SomeInternalClass()//变量为internal <= 类型为internal
internal let someInternal3 = SomePublicClass()//变量为internal <= 类型为public
//Error:public let somePublic1 = SomePrivateClass() //变量public大于类型private,错误
//Error:public let somePublic2 = SomeInternalClass() //变量public大于类型internal,错误
public let somePublic3 = SomePublicClass()//变量为public <= 类型为public
3.【Setter <= Getter】
/* 3.【setter <= getter】,private(set)修饰将setter权限设置为private */
/*
这个规定适用于用作存储的属性或用作计算的属性。
即使你不明确的申明存储属性的Getter、Setter,
Swift也会隐式的为其创建Getter和Setter,用于对该属性进行读取操作。
*/
public class SetterPrivateClass {//该类可以在任何模块中使用
private(set) var value = 0 //设置存储属性的setter为private
//设置计算属性的setter属性为private
private(set) var setPrivateProperty:Int {
set{//此时setter为private,也就是只能在本文件中使用,其他文件无法使用
value = newValue + 1
}
get{//getter默认为internal
return value + 1
}
}
}
4.【required方法 == 类】【默认逐一构造函数 <= 所有成员】
/* 4.【required修饰的方法 == 类】,(结构体)【默认逐一构造函数 <= 所有成员】 */
protocol RequiredTestProtocol {
//初始化构造器要求
init(aprot: Int)
}
public class RequiredTestClass: RequiredTestProtocol {
var aprot: Int //默认为internal
//实现协议的初始化要求时,必须使用required关键字确保子类必须也得实现这个构造器
public required init(aprot: Int) {//此时必须设置为public,因为默认是internal的
self.aprot = aprot
}
}
//该结构体的默认逐一构造方法为private,但默认构造方法还是internal
public struct StructInitTest{
private var somePrivateProperty = 0
internal var someInternalProperty = 0
public var somePublicProperty = 0
}
5.【子类 <= 父类】【子协议 <= 父协议】
/* 5.【子类 <= 父类】,【子协议 <= 父协议】 */
private class PrivateSuperClass { } //private父类
internal class InternalSuperClass { }//internal父类
public class PublicSuperClass { }//public父类
private class PrivateSubClass1:PrivateSuperClass { } //子类private <= private父类
private class PrivateSubClass2:InternalSuperClass { } //子类private <= internal父类
private class PrivateSubClass3:PublicSuperClass { } //子类private <= public父类
//Error:internal class InternalSubClass1:PrivateSuperClass { } //子类internal大于private父类,错误
internal class InternalSubClass2:InternalSuperClass { } //子类internal <= internal父类
internal class InternalSubClass3:PublicSuperClass { } //子类internal <= public父类
//Error:public class PublicSubClass1:PrivateSuperClass { } //子类public大于private父类,错误
//Error:public class PublicSubClass2:InternalSuperClass { } //子类public大于internal父类,错误
public class PublicSubClass3:PublicSuperClass { } //子类public <= public父类
6. 子类重写父类成员修改访问范围
/* 6.不违反前面规则,子类可以通过重写父类方法来修改访问权限范围 */
public class OverrideSuperClass {
private func someMethod() {}
}
internal class OverrideSubClass: OverrideSuperClass {
override internal func someMethod() {
super.someMethod()//子类和父类在同一个源文件中,所以可以访问super的someMethod()方法
}
}
7.【协议成员 == 协议】【类 >= 协议】【协议实现 >= 协议要求】
/* 7.【协议所有必须实现的成员 == 协议】,【类 >= 协议】,【协议实现 >= 协议要求】 */
internal protocol InternalProtocol {
//协议成员不可以添加访问控制关键字,默认等于协议的访问权限范围
var someProperty:Int { get set }
func someMethod()
}
//类必须大于或等于要遵循的协议
public class ProtocolTestClass:InternalProtocol {
//Error:-> private var someProperty = 0 //协议实现必须大于或等于协议要求
public var someProperty = 0
internal func someMethod() {
print("ProtocolTestClass someMethod")
}
}
8.【元组 = Min(所有元素类型)】
/* 8.【元组 = Min(所有元素类型)】,注意是类型而不是变量 */
private var privateValue = SomePrivateClass() //注意,看类型访问级别而不是变量访问级别
var internalValue = SomeInternalClass()
var publicValue = SomePublicClass() //这里变量是internal的,但类型是public的
private let privateTupleValue = (privateValue, internalValue, publicValue)
internal let internalTupleValue = (internalValue, internalValue, publicValue)
public let publicTupleValue = (publicValue, publicValue, publicValue)
9.【函数 = Min(参数类型,返回值类型)】
/* 9.【函数 = Min(参数类型,返回值类型)】 */
private func someFunction(value:SomeInternalClass) -> SomePrivateClass {
//函数体
return SomePrivateClass()
}
10.【枚举成员 == 枚举】【(原始值,关联值) >= 枚举】
/* 10.【枚举成员 == 枚举】,枚举成员没法单独设置访问级别,【(原始值,关联值) >= 枚举】 */
private enum PrivateEnum {
case PrivateEnumCase( SomePrivateClass )
case InternalEnumCase( SomeInternalClass )
case PublicEnumCase( SomePublicClass )
}
internal enum InternalEnum {
//Error:-> case PrivateEnumCase( SomePrivateClass ) //关联值必须大于枚举
case InternalEnumCase( SomeInternalClass )
case PublicEnumCase( SomePublicClass )
}
11.【泛型类型 = Min(类类型,泛型参数)】
/* 11.【泛型类型 = Min(类类型,泛型参数)】 */
public class GenericityClass<T> {
var value = [T]()
func someFunction(value:T) { }
}
private let genericityPrivate = GenericityClass<SomePrivateClass>() //泛型类型为private
internal let genericityInternal = GenericityClass<SomeInternalClass>() //泛型类型为internal
public let genericityPublic = GenericityClass<SomePublicClass>() //泛型类型为public
//Error:public let genericityInternal = GenericityClass<SomeInternalClass>() //泛型类型为internal
12.【类型别名 <= 原类型】
/* 12.【类型别名 <= 原类型】 */
//包含类型别名的类,遵循【成员<=类】
public class MyClass {
//声明一个类型别名,类型别名是一个为已存在类型定义的一个可选择的名字
private typealias privateName1 = SomePrivateClass
private typealias privateName2 = SomeInternalClass
private typealias privateName3 = SomePublicClass
//internal的类型别名可以是internal、public的类型,不可以是private类型
//Error:-> internal typealias internalName1 = SomePrivateClass
internal typealias internalName2 = SomeInternalClass
internal typealias internalName3 = SomePublicClass
//public的类型别名只能是public的类型
//Error:-> public typealias publicName1 = SomePrivateClass
//Error:-> public typealias publicName2 = SomeInternalClass
public typealias publicName3 = SomePublicClass
private var someProperty = privateName1()
}
iOS学习笔记49-Swift(九)访问控制的更多相关文章
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- iOS学习笔记总结整理
来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
- iOS学习笔记——AutoLayout的约束
iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- IOS学习笔记之关键词@dynamic
IOS学习笔记之关键词@dynamic @dynamic这个关键词,通常是用不到的. 它与@synthesize的区别在于: 使用@synthesize编译器会确实的产生getter和setter方法 ...
- iOS学习笔记10-UIView动画
上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...
- 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap
[Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...
- iOS学习笔记之Category
iOS学习笔记之Category 写在前面 Category是类别(也称为类目或范畴),使用Category,程序员可以为任何已有的类添加方法.使用类别可以对框架提供的类(无法获取源码,不能直接修改) ...
- iOS学习笔记之ARC内存管理
iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...
随机推荐
- setup命令
setup——配置网络(centos) 命令所在路径:usr/bin/setup 示例1: # setup
- [CV笔记]图像特征提取三大法宝:HOG特征,LBP特征,Haar特征
(一)HOG特征 1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和 ...
- C++STL概览
本文转自http://www.cnblogs.com/ggjucheng/archive/2012/01/03/2310884.html 引言 C++ STL可以分为标准容器,算法和函数对象,迭代器和 ...
- 两个有序数列,求中间值 Median of Two Sorted Arrays
原题: There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the median of the ...
- alibaba druid监控页面的使用配置
一.Maven中添加Durid连接池依赖 <!-- druid连接池 --> <dependency> <groupId>com.alibaba</group ...
- VS Code:设置多行注释快捷键
多行注释,也叫块注释. 如何查看,并修改VS Code中的多行注释快捷键呢? 1). 点击 首选项 - 键盘快捷方式 2). 在搜索框中输入 comment 3). 这个时候可以看到“切换块注释”的信 ...
- 作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
- rem和em的区别
原文链接:http://caibaojian.com/rem-vs-em.html rem 单位如何转换为像素值 当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的 ...
- vue-awesome-swiper插件爬坑
最近自己在做一个基于vue的知乎的移动端单页面,遇到很多坑,先说一下遇到最大的坑,其实并不推荐使用 vue-awesome-swiper,如果项目应用轮播,切换少的话.言归正传,现在来介绍vue-aw ...
- 利用wget 和 curl 监控网站是否正常
监控网站URL是否正常最常见的方法莫过于wget和curl命令了,这两个命令都是非常强大,参数也非常多,下面列举几个常用的参数. wget 常用命令参数:--spider ...