【Swift】アクセス修飾子(private, fileprivate,intenal, public, open)の違いとは?わかりやすく解説

今回はSwiftにおけるアクセス修飾子の違いについて。

アクセス修飾子とは、クラス、構造体、プロパティ、メソッドなどのアクセス範囲を指定するキーワードのことだ。

Swiftにおけるアクセス修飾子は下記5つの種類がある。

アクセス修飾子概要
openどこからでもアクセス可能
publicどこからでもアクセス可能。但し、他のモジュール(他のアプリ等)からの継承不可
internalデフォルト。同じプロジェクト内(つまり、同じアプリ内)のみアクセス可能
fileprivate同じファイル内からのみアクセス可能
private同じクラスや構造体等からのみアクセス可能

アクセス可能な範囲はprivate → fileprivate → internal → public → open の順で緩くなる。

つまり、privateがアクセス制限が最も厳しく、openが最も甘い。

よく使うのはprivateとinternalだと思うが、私はこの違いが最初の頃だいぶ曖昧だったので、簡単に整理しておきたい。

スポンサーリンク

open

openは最もアクセス範囲が広いアクセス修飾子だ。

モジュール外(アプリ外)からも継承可能であり、プロパティやメソッドのオーバーライド(上書き)も可能となる。

APIやライブラリとしてクラスを定義する場合はこのopenか後述するpublicを指定する。

その中でも特に、外部モジュールでクラスを拡張したりオーバーライドしたりしたい場合にopenを使用する。

スポンサーリンク

public

publicはopenに似ていて、クラスはモジュール外での利用可能だ。

ただし、継承やオーバーライドは同じモジュール内(アプリ内)でしか行えない点がopenとの違いだ。

他のモジュールからクラスやメソッドにアクセスさせたいが、継承やオーバーライドを制限したい場合はpublicを使用する。

internal

internalは、同一モジュール内(同じアプリ内)からのアクセスのみが可能となるアクセス修飾子だ。

同じアプリ内からは自由にアクセスできるが、他のモジュール(他のアプリ等)からは一切アクセスできない。

このinternalはSwiftのデフォルトのアクセスレベルだ。

そのため、省略して使われていることが多く、馴染みがない人も多いかもしれない。

例えば、下記2つのコードのアクセスレベルはどちらも同じinternalとなり、同じアプリ内からしかアクセスできない。

【明示的にinternalを指定した場合】

【internalを省略する場合】

アプリ内からもアクセス制限を掛ける必要があったり、外部からアクセスできるようにしたりする必要がなければ、アクセスレベルはこのinternalを使えばOKだ。

fileprivate

fileprivateは同じファイル内からのみアクセスが可能となるアクセスレベルだ。

デフォルトのアクセスレベルのinternalはアプリ内のどのファイルからもアクセス可能だったが、fileprivateの場合は他のファイルからアクセスすることはできない。

もし、同じアプリ内の別ファイル(~.swift)からアクセスしようとすると下記のようにXcode上でエラーが発生する

例えば、File1.swiftというファイルに下記コードがあるとする。

このメソッドを同じアプリ内のContentView.swiftファイルで下記のように呼び出そうとすると前述したエラーがXcode上で表示される。

理由はFile1.swiftファイル内からではなく、ContentView.swiftという別ファイルからfileprivateのアクセスレベルに設定したメソッドを呼び出したからだ。

このrevealSecret()メソッドの先頭に指定してある fileprivate を削除して、デフォルトのinternalのアクセスレベルに変更するとエラーが解消する。

もしくはContentView.swiftファイル内にFilePrivateClassを移動させてしまえば、同じファイル内での呼び出しになり、こちらでもエラーが解消する。

このようにfileprivateを指定すると他のファイルからはアクセスできないため、ファイル内でのみ動作するプライベートな機能を実装する場合に利用する。

private

privateはfileprivateよりも更にアクセスレベルが制限される。

同じクラスや構造体の内部でのみアクセス可能となるのがprivateだ。

当然、アプリ外やアプリ内の他のファイルからのアクセスも出来ない。

fileprivateとの違いは同じファイル内の別のクラスや構造体からのアクセスもエラーになる点だ。

例えば、先ほどfileprivateの例で違いを確認しよう。

【ContentView構造体で同じファイル内のfileprivateのメソッドを呼び出し】

上記は先ほど説明した通りで、fileprivateのメソッドを同じファイル内のContentView構造体から呼び出しているのでエラーは起きない。

一方で上記コードのアクセスレベルをfileprivateからprivateに変えるだけで今度はエラーとなる。

理由はFilePrivateClassで定義されたprivateメソッドを同じファイル内のContentView構造体というFilePrivateClassとは別の構造体で呼び出そうとしているからだ。

クラスや構造体の内部のみで利用したい場合はprivateを利用しよう。

まとめ

Swiftにおける5つのアクセス修飾子の要点は下記のとおりだ。

  • アクセスレベルはprivate → fileprivate → internal → public → open の順で緩くなる。
  • privateが最もアクセス制限が厳しく、同一クラスや構造体からしかアクセスできない
  • fileprivateは同じファイル内からのみアクセス可能
  • internalはデフォルトのアクセスレベルで同じアプリ内からは別ファイルからでもアクセス可能。省略される事が多い
  • publicとopenはどちらも他のモジュール(他のアプリ等)からアクセス可能でライブラリ等でよく使われる
  • publicはopenと違い、継承やオーバーライドは同じモジュール内(アプリ内)でしか行えない

 

おすすめの記事