(转载的,暂时没有研究过这类语句,有空看看)

在swift 3中新增加了两种访问控制权限 fileprivate open。下面将对这两种新增访问控制做详细介绍。

fileprivate

在原有的swift中的 private其实并不是真正的私有,如果一个变量定义为private,在同一个文件中的其他类依然是可以访问到的。这个场景在使用extension的时候很明显。

class User {
    private var name = "private"
}

extension User{
    var accessPrivate: String {
        return name
    }
}

这样带来了两个问题:

  • 当我们标记为private时,意为真的私有还是文件内可共享呢?
  • 当我们如果意图为真正的私有时,必须保证这个类或者结构体在一个单独的文件里。否则可能同文件里其他的代码访问到。

由此,在swift 3中,新增加了一个 fileprivate来显式的表明,这个元素的访问权限为文件内私有。过去的private对应现在的fileprivate。现在的private则是真正的私有,离开了这个类或者结构体的作用域外面就无法访问。

open

open则是弥补public语义上的不足。
现在的pubic有两层含义:

  • 这个元素可以在其他作用域被访问
  • 这个元素可以在其他作用域被继承或者override

继承是一件危险的事情。尤其对于一个framework或者module的设计者而言。在自身的module内,类或者属性对于作者而言是清晰的,能否被继承或者override都是可控的。但是对于使用它的人,作者有时会希望传达出这个类或者属性不应该被继承或者修改。这个对应的就是 final

final的问题在于在标记之后,在任何地方都不能override。而对于lib的设计者而言,希望得到的是在module内可以被override,在被import到其他地方后其他用户使用的时候不能被override。

这就是 open产生的初衷。通过open和public标记区别一个元素在其他module中是只能被访问还是可以被override。

下面是例子:

/// ModuleA:

// 这个类在ModuleA的范围外是不能被继承的,只能被访问
public class NonSubclassableParentClass {

    public func foo() {}

    // 这是错误的写法,因为class已经不能被继承,
    // 所以他的方法的访问权限不能大于类的访问权限
    open func bar() {}

    // final的含义保持不变
    public final func baz() {}
}

// 在ModuleA的范围外可以被继承
open class SubclassableParentClass {
    // 这个属性在ModuleA的范围外不能被override
    public var size : Int

    // 这个方法在ModuleA的范围外不能被override
    public func foo() {}

    // 这个方法在任何地方都可以被override
    open func bar() {}

    ///final的含义保持不变
    public final func baz() {}
}

/// final的含义保持不变
public final class FinalClass { }
/// ModuleB:

import ModuleA

// 这个写法是错误的,编译会失败
// 因为NonSubclassableParentClass类访问权限标记的是public,只能被访问不能被继承
class SubclassA : NonSubclassableParentClass { }

// 这样写法可以通过,因为SubclassableParentClass访问权限为 `open`.
class SubclassB : SubclassableParentClass {

    // 这样写也会编译失败
    // 因为这个方法在SubclassableParentClass 中的权限为public,不是`open'.
    override func foo() { }

    // 这个方法因为在SubclassableParentClass中标记为open,所以可以这样写
    // 这里不需要再声明为open,因为这个类是internal的
    override func bar() { }
}

open class SubclassC : SubclassableParentClass {
    // 这种写法会编译失败,因为这个类已经标记为open
    // 这个方法override是一个open的方法,则也需要表明访问权限
    override func bar() { }
}

open class SubclassD : SubclassableParentClass {
    // 正确的写法,方法也需要标记为open
    open override func bar() { }
}

open class SubclassE : SubclassableParentClass {
    // 也可以显式的指出这个方法不能在被override
    public final override func bar() { }
}

总结

现在的访问权限则依次为:open,public,internal,fileprivate,private。
有的人会觉得访问权限选择的增加加大了语言的复杂度。但是如果我们思考swift语言的设计目标之一就是一门安全的语言(“Designed for Safety”)就能理解这次的改动。更加明确清晰的访问权限控制可以使程序员表达出更准确的意图,当然也迫使在编码时思考的更加深入。

欢迎关注我的微博:@没故事的卓同学
相关链接:
SE0025-Scoped Access Level
SE0117-Allow distinguishing between public access and public overridability

文/没故事的卓同学(简书作者)
原文链接:http://www.jianshu.com/p/604305a61e57
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Swift基础之:新的访问控制fileprivate和open的更多相关文章

  1. Swift 3:新的访问控制fileprivate和open

    在swift 3中新增加了两种访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...

  2. Swift 3中新的访问控制关键字fileprivate和open

    在Swift 3中除去原有的3个访问控制关键字private,public,internal,又添加了2个关键字fileprivate和open 它们可以看成是对private和public的进一步细 ...

  3. Swift 3必看:新的访问控制fileprivate和open

    在swift 3中新增加了两中访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...

  4. swift基础:第六部分:类与对象

    http://reactnative.cn/docs/0.24/getting-started.html#content(react Native 开发文档) 互联网这个时代,你松懈一天,就会有很多很 ...

  5. Swift基础语法学习总结(转)

    Swift基础语法学习总结 1.基础  1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型 ...

  6. Swift基础语法学习总结

    Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.基础  1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift ...

  7. iOS开发——新特性OC篇&Swift 2.0新特性

    Swift 2.0新特性     转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...

  8. swift基础:第二部分:函数和闭包

    今天本来想利用上午的时间本来打算将swift基础部分学习完的,不巧的是,后台来和我讨论用户评价的接口,讨论过后,商讨出一种可行的方案,十几分钟时间过去了,我拿到将接口介入到已经完成的页面中,完美,终于 ...

  9. swift -- 基础

    swift -- 基础 1.常量和变量 常量: let 变量: var 2.声明常量和变量 常量的声明: let let  a = 1         //末尾可以不加分号,等号两边的空格必须对应(同 ...

随机推荐

  1. 【实用】【移动端】Retain屏1px解决方案

    新浪微博HTML5版 微博的实现方式(rem + 小数px) <meta name="viewport" content="width=device-width,i ...

  2. 关于ajax的content-download时间过慢问题的解决方案与思考

    前言:   做前端架构很久很久了,经常到我这里都是些棘手的问题,之前没有养成很好的记录问题的习惯,以后会努力成文,积累. 于是今天就有个这篇文章.关于ajax的content-download时间过慢 ...

  3. JavaScript反调试技巧

    一.函数重定义 这是一种最基本也是最常用的代码反调试技术了.在JavaScript中,我们可以对用于收集信息的函数进行重定义.比如说,console.log()函数可以用来收集函数和变量等信息,并将其 ...

  4. 在vue中操作DOM--this.$nextTick()

    虽然 Vue.js 通常鼓励开发人员沿着"数据驱动"的方式思考,避免直接接触 DOM,但是有时我们确实要这么做.比如一个新闻滚动的列表项.如果在这里需要操作dom, 应该是等待 V ...

  5. substr函数用法详解

    substr(string, start<,length>):从string的start位置开始提取字符串 length:要提取字符串的长度,若length为以下任意条件之一时,返回sta ...

  6. Python中的数据类型

    计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定义不同的数 ...

  7. [self init]

    在字典转模型中遇到了这样的代码: #import "HMAppInfo.h" @implementation HMAppInfo - (instancetype)initWithD ...

  8. ACM Curling 2.0

    在行星MM-21上,今年奥运会之后,冰壶(curling)越来越受欢迎.  但规则与我们有所不同. 该游戏是在冰盘上进行的,在冰棋盘上标有方形网格.他们只用一块石头. 游戏的目的是以最少的动作( th ...

  9. Docker基本架构

    Docker 采用了 C/S架构,包括客户端和服务端. Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建.运行.分发容器). 客户端和服务端既可以运行在一个机器上,也可通 ...

  10. 百度地图JS 搜索悬浮窗功能

    这个需求的效果类似下面的截图,主要还是利用百度地图中自定义控件的功能,挺简单的.文档地址在这 http://lbsyun.baidu.com/index.php?title=jspopular 效果图 ...