![[Swift 3.0] アクセス修飾子にopenとfileprivateが追加された話](https://devio2023-media.developers.io/wp-content/uploads/2014/11/logo_swift_400x400.png)
[Swift 3.0] アクセス修飾子にopenとfileprivateが追加された話
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Swift3.0からopenとfileprivateという新たなアクセス修飾子(Access Control)が追加されました。
Swift Evolutionでいうところの下記の内容です。
0025-scoped-access-level
0117-non-public-subclassable-by-default
| open | モジュール外からもアクセスできる。 一番ゆるいアクセスコントロール。 新規追加✨ | 
| public | モジュール外からもアクセスできる。 サブクラス化されない。 overrideできない。 | 
| internal | モジュール内ならアクセスできる。 何も書かないとコレになる。(デフォルト) | 
| fileprivate | 文字通りファイル内ならアクセスできる。 新規追加✨ | 
| private | クラスなど宣言内でしかアクセスできない。 | 
open
今回新しく追加された修飾子です。
以前、Public は他のモジュールがインスタンス化したクラスを使用することができ、サブクラスを定義することができました。また、メンバー(method, property, subscript) をOverrideすることができました。
Swift3.0 から新しくopenが追加され、これらの概念が区別されました。
open、publicともに他のモジュールからの使用は可能ですが、publicの方はサブクラス化されません。
| 以前 | Swift3 | |
| overrideできない サブクラス化されない | final public | → public | 
| overrideできる サブクラス化される | public | → open | 
また、現時点でのSwift3の仕様では、openを利用するには、スーパークラスもopenでないといけません。
モジュール(module)とは?
ライブラリなどimportを使って取り込むまとまりです。
UIKit、MapKit、CoreData、CoreImageなどが該当します。
Swift2.x(今までの例)
public class UIViewController : UIResponder, NSCoding, UIAppearanceContainer, UITraitEnvironment, UIContentContainer, UIFocusEnvironment {
    // 一部抜粋
    public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
    public init?(coder aDecoder: NSCoder)
    public var view: UIView!
    public func loadView()
    public func viewDidLoad()
    ・
    ・
    ・
Swift3.0
open class UIViewController : UIResponder, NSCoding, UIAppearanceContainer, UITraitEnvironment, UIContentContainer, UIFocusEnvironment {
    // 一部抜粋
    public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
    public init?(coder aDecoder: NSCoder)
    open var view: UIView!
    open func loadView()
    open func viewDidLoad() 
    ・
    ・
    ・
fileprivate
同じファイル内であればアクセスできるようにしたのがfileprivateです。
Swift2.x(今までの例)
class Cat {
  private let name = "cat"
}
class Dog {
  func callCat() {
     let cat = Cat()
     print(cat.name)
  }
}
Swift3.0
class Cat {
  fileprivate let name = "cat"
}
class Dog {
  func callCat() {
     let cat = Cat()
     print(cat.name)
  }
}
Swift2.xまでは同じファイル内であればprivateでもアクセス出来ていたようですが、Swift3.0からは明示的にfileprivateとしなければアクセス出来ないようになりました。
さいごに
今回増えたことによって、アクセスレベルがより明確化されました
ライブラリを作っている人とprivateで同じファイル内で参照していた人以外は特に大きな影響は無さそうに思います。

















