Swift面向对象之私有化

前言

在所有面向对象编程语言中有一个共同的特性:为安全考虑,任何没有必要公开的属性、变量和函数都应该定义为私有,以免被误操作修改。前面讲到在 Swift 中,同一命名空间下的所有文件都为共享,这明显不符合 OO 语言的标准。那么 Swift 中是如何定义私有属性的呢?接下来就探索一下 Swift 的私有化处理。

简介

Swift 中访问修饰符有5种,分别为 fileprivateprivateinternalpublicopen,其中 fileprivateopenSwift3.0 新添加的。由于过去 Swift 对于访问权限的控制,不是基于类的,而是基于文件的。这样会有问题,所以 Swift 3.0 新增了两个修饰符对原来的 privatepublic 进行细分。

各修饰符的功能与区别

  • internal
    默认访问级别,该修饰符可写可不写,它修饰的属性或函数在同一命名空间下都可以被访问。如果修饰的是框架或者库代码,则在整个框架或库中可以被访问,框架被外部代码引用时不可以访问,同一个 app 只有一个命名空间,整个 app 内部可以访问。
    import UIKit
    
    internal class A {
       internal func show() {
            print("这是一个私有函数")
        }
    }
    internal class B : A {
        func test() {
            show()
        }
    }
    internal class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let b = B()
            b.test()
        }
    }
    
    Swift面向对象之私有化_第1张图片
    internal访问权限输出

    从上面代码中可以看出 class B 继承自 class A,那么 class A 中所有的公有属性都可以被 class B 访问到,这样做 class A 就没有任何私密可言,外界可以很轻易的修改 class A 中的东西,这样做明显是不安全的,下面就通过几个修饰符来确保类的私有化。

  • private
    Swift 3 中该修饰符所修饰的属性或者函数只能在当前类里访问,Swift 4extension 里也可以访问被 private 修饰的属性和函数。如果需要使用 KVC 为属性赋值,一定不能用此修饰符。
    Swift面向对象之私有化_第2张图片
    private效果展示

    添加了 private 修饰符后的报错信息,当父类的某个属性或者函数被 private 修饰后,子类是无法访问到的。
    Swift面向对象之私有化_第3张图片
    Swift 4.0中extension访问私有属性展示

    上图中的操作在 Swift 3.0 中是被禁止的,在 Swift 4.0 是合法的。
  • fileprivate
    该修饰符所修饰的属性或者方法在当前的 Swift 文件里可以访问。
    Swift面向对象之私有化_第4张图片
    fileprivate权限展示

    上图中将 private 改成 fileprivate 之后,子类可以正常访问父类信息,但其他类是无法访问到 class A的 Show()
    Swift面向对象之私有化_第5张图片
    fileprivate错误操作展示
  • public
    被该修饰符修饰的属性或者函数可以在任何地方被访问,但在 module 外不可以被重写(override) 和继承(Inheritance)。不需要使用 import 引入就可以创建该对象的称之为 module 内,需要 import 引入才可以创建该对象的称之为 module 外。抱歉,这个修饰符我想不到办法展示。
  • open
    被该修饰符修饰的属性或者函数可以在任何地方被访问,也可以被重写(override) 和继承。

总结

  • internal 默认访问级别,同一命名空间下可以被访问;
  • private 绝对私有,除了自己和 extension 以外任何地方都不可以被访问,KVC 无法通过路径找到被 private 修饰的属性;
  • fileprivate 相对私有,在同一文件内可以被访问;
  • public 相对公有,可以在任何地方被访问,但在 module 外不可以被重写和继承。
  • open 绝对公有,可以在任何地方被访问和重写以及继承。

你可能感兴趣的:(Swift面向对象之私有化)