Swift アクセス制御
アクセス制御は、他のソースファイルやモジュール内のコードがあなたのコードにアクセスするレベルを制限できます。
特定の型(クラス、構造体、列挙型)にアクセスレベルを明示的に設定できるだけでなく、それらの型のプロパティ、関数、初期化メソッド、基本型、サブスクリプトなどにもアクセスレベルを設定できます。
プロトコルも特定の範囲内での使用に限定できます。プロトコル内のグローバル定数、変数、関数も含みます。
アクセス制御はモジュールとソースファイルに基づきます。
モジュールとは、独立したユニットとして構築・公開される Framework または Application のことです。Swift のモジュールは、import キーワードを使用して別のモジュールを導入できます。
ソースファイルは単一のソースコードファイルであり、通常は1つのモジュールに属します。ソースファイルには複数のクラスや関数の定義を含めることができます。
Swift はコード内のエンティティに対して、4つの異なるアクセスレベルを提供します:public、internal、fileprivate、private。
| アクセスレベル | 定義 |
|---|---|
| public | 自分のモジュール内のソースファイルにある任意のエンティティにアクセスでき、他のモジュールからもそのモジュールを import することでソースファイル内のすべてのエンティティにアクセスできます。 |
| internal | 自分のモジュール内のソースファイルにある任意のエンティティにはアクセスできますが、他のモジュールからはそのモジュールのソースファイル内のエンティティにアクセスできません。 |
| fileprivate | ファイル内プライベート(fileprivate)。現在のソースファイル内でのみ使用できます。 |
| private | クラス内でのみアクセス可能です。そのクラスや構造体のスコープの外ではアクセスできません。 |
public は最も高いアクセスレベルで、private は最も低いアクセスレベルです。
構文
修飾子 public、internal、fileprivate、private を使用してエンティティのアクセスレベルを宣言します:
例
特別な指定がない限り、エンティティはデフォルトのアクセスレベル internal を使用します。
アクセスレベルを指定しない場合、デフォルトは internal です
関数型のアクセス権限
関数のアクセスレベルは、その関数のパラメータ型と戻り値型のアクセスレベルに基づいて決まります。
次の例では、someFunction という名前のグローバル関数を定義していますが、そのアクセスレベルは明示的に宣言されていません。
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 函数实现
}
関数内のクラス SomeInternalClass のアクセスレベルは internal、もう1つの SomePrivateClass のアクセスレベルは private です。したがって、タプルのアクセスレベルに関する原則に基づき、そのタプルのアクセスレベルは private になります(タプルのアクセスレベルは、タプル内で最も低いアクセスレベルの型と一致します)。
関数の戻り値型のアクセスレベルが private であるため、private 修飾子を使用して関数を明示的に宣言する必要があります:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 函数实现
}
この関数を public または internal として宣言するか、デフォルトのアクセスレベル internal を使用するのは誤りです。その場合、private レベルの戻り値にアクセスできないからです。
列挙型のアクセス権限
列挙型のメンバーのアクセスレベルは、その列挙型から継承されます。列挙型のメンバーに個別に異なるアクセスレベルを宣言することはできません。
例
たとえば、次の例では、列挙型 Student が明示的に public レベルで宣言されているため、そのメンバー Name、Mark のアクセスレベルも同様に public になります:
例
上記プログラムの実行出力結果は次のとおりです:
学生成绩: 98,97,95
サブクラスのアクセス権限
サブクラスのアクセスレベルは、スーパークラスのアクセスレベルより高くすることはできません。たとえば、スーパークラスのアクセスレベルが internal の場合、サブクラスのアクセスレベルを public と宣言することはできません。
例
上記プログラムの実行出力結果は次のとおりです:
スーパークラス サブクラス
定数、変数、プロパティ、サブスクリプトのアクセス権限
定数、変数、プロパティは、その型よりも高いアクセスレベルを持つことはできません。
たとえば、public レベルのプロパティを定義しても、その型が private レベルの場合、コンパイラはこれを許可しません。
同様に、サブスクリプトも、インデックス型や戻り値型よりも高いアクセスレベルを持つことはできません。
定数、変数、プロパティ、サブスクリプトの定義型が private レベルの場合、それらは明示的にアクセスレベルを private と宣言する必要があります:
private var privateInstance = SomePrivateClass()
Getter と Setter のアクセス権限
定数、変数、プロパティ、サブスクリプトの Getter と Setter のアクセスレベルは、それらが属するメンバーのアクセスレベルを継承します。
Setter のアクセスレベルは、対応する Getter のアクセスレベルより低くすることができます。これにより、変数、プロパティ、またはサブスクリプトの読み取り・書き込み権限を制御できます。
例
counter のアクセスレベルは fileprivate であり、ファイル内でアクセスできます。
上記プログラムの実行出力結果は次のとおりです:
计数器: 100 新增加数量 100 计数器: 800 新增加数量 700
イニシャライザとデフォルトイニシャライザのアクセス権限
初期化
カスタムイニシャライザにはアクセスレベルを宣言できますが、それが属するクラスのアクセスレベルより高くすることはできません。ただし、必須イニシャライザは例外で、そのアクセスレベルは所属するクラスのアクセスレベルと同じでなければなりません。
関数やメソッドのパラメータと同様に、イニシャライザのパラメータのアクセスレベルも、イニシャライザのアクセスレベルより低くすることはできません。
デフォルトイニシャライザ
Swift は構造体とクラスに、すべてのプロパティに値を割り当てるためのデフォルトの引数なしイニシャライザを提供しますが、具体的な値は指定しません。
デフォルトイニシャライザのアクセスレベルは、所属する型のアクセスレベルと同じです。
例
各サブクラスの init() メソッドの前に required キーワードを使用してアクセス権限を宣言します。
例
上記プログラムの実行出力結果は次のとおりです:
10 30 10
プロトコルのアクセス権限
プロトコルにアクセスレベルを明示的に宣言する場合は、宣言したアクセスレベルのスコープ内でのみそのプロトコルを使用するようにする必要があることに注意してください。
public アクセスレベルのプロトコルを定義した場合、そのプロトコルを実装するために提供される必要な関数も public のアクセスレベルになります。これは他の型とは異なります。たとえば、public アクセスレベルの他の型では、そのメンバーのアクセスレベルは internal です。
例
上記プログラムの実行出力結果は次のとおりです:
res is: 20 res is: 30 res is: 50
拡張のアクセス権限
条件が許せば、クラス、構造体、列挙型を拡張できます。拡張メンバーは、元のクラスのメンバーと同じアクセスレベルを持つ必要があります。たとえば、パブリック型を拡張する場合、新しく追加するメンバーは元のメンバーと同じデフォルトの internal アクセスレベルを持つ必要があります。
あるいは、拡張のアクセスレベルを明示的に宣言して(たとえば private extension を使用)、拡張内のすべてのメンバーに新しいデフォルトのアクセスレベルを設定できます。この新しいデフォルトのアクセスレベルは、個々のメンバーが宣言するアクセスレベルによって上書きされることもあります。
ジェネリックのアクセス権限
ジェネリック型またはジェネリック関数のアクセスレベルは、ジェネリック型、関数自体、ジェネリック型パラメータのうち、最も低いアクセスレベルになります。
例
上記プログラムの実行出力結果は次のとおりです:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]
型エイリアス
定義した型エイリアスは、アクセス制御の目的で異なる型として扱われます。型エイリアスのアクセスレベルは、元の型のアクセスレベルより高くすることはできません。
たとえば、private レベルの型エイリアスは、public、internal、private のいずれの型にも設定できます。しかし、public レベルの型エイリアスは public レベルの型にのみ設定でき、internal または private レベルの型には設定できません。
注意:この規則は、プロトコル準拠を満たすために関連する型にエイリアスを付ける場合にも適用されます。
例
以上のプログラムを実行した出力結果は次のとおりです。
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "Where 语句"] ["Swift", "泛型", "Where 语句"]その他の拡張機能