【プログラミング初心者】Swift基礎~アクセス修飾子~


はじめに

今回はオブジェクト指向の考え方の1つであるカプセル化を実現するためのアクセス修飾子の使い方について紹介します。
カプセル化がどういうものかはこちらで紹介しているので参照してください。

アクセス修飾子

アクセス修飾子はそのプロパティもしくはメソッドを外から呼べるかどうかの権限を表します。
これは定義の頭に付けるもので構文は以下となります。

アクセス修飾子構文
// プロパティの場合
アクセス修飾子 var 変数: 

// メソッドの場合
アクセス修飾子 func メソッド名() {

}

見ればわかるようにいつもの定義の仕方の頭にアクセス修飾子を付けるだけですね。

Swiftのアクセス修飾子は以下の5種類があります。
上から順に制約はゆるくなります。

アクセス修飾子 概要
private クラス内からしかアクセスできない
fileprivate 同じファイル内からしかアクセスできない
internal 同じモジュール内からはどこからでもアクセスできる
public 他のモジュールからもアクセスできるがオーバーライドできない
open 他のモジュールからもアクセスでき、オーバーライドできる

よく使うのはprivateinternalになるかと思います。
この2つについて具体的な実装を紹介します。

private

最も厳しいアクセス修飾子でクラス内でしか呼び出せないプロパティ、メソッドに付けます。

class MyClass {
    private var privateProperty = 0

    private func privateMethod() {
        print("privateMethod")
    }

    func testMethod() {
        self.privateMethod() // OK
        let tmp = self.privateProperty // OK
    }
}

let myClass = MyClass()
myClass.privateMethod()  // NG
let tmp = myClass.privateProperty // NG

noPrivateMethod()での呼び出しのようにクラス内で扱う時は特に気にする必要はありません。
クラスの外から呼び出そうとすると
'privateMethod' is inaccessible due to 'private' protection level
'privateProperty' is inaccessible due to 'private' protection level
というように怒られます。
※そもそもprivateで指定したメソッド、プロパティは補完候補にも挙がってきません。

internal

「同じモジュール内からはどこからでもアクセスできる」と説明しています。
モジュールとありますが今はそれほど意識しなくても構いません。
アプリ内であればどこからでもアクセスできるととりあえずは覚えてください。

またアクセス修飾子なしでメソッド、プロパティを定義するとinternalとして扱われます。
そのため自分でinternalと指定することはあまりないかと思います。

以下実装例です。

class MyClass {
    internal var privateProperty1 = 0
    var privateProperty2 = 0

    internal func internalMethod1() {
        print("internalMethod1")
    }

    func internalMethod2() {
        print("internalMethod1")
    }

    func testMethod() {
        self.internalMethod1() // OK
        self.internalMethod2() // OK
        let tmp1 = self.privateProperty1 // OK
        let tmp2 = self.privateProperty2 // OK
    }
}

let myClass = MyClass()
myClass.internalMethod1() // OK
myClass.internalMethod2() // OK
let tmp1 = myClass.privateProperty1 // OK
let tmp2 = myClass.privateProperty2 // OK

このように外から参照できるものは今まで通り何も付けない or internalを付けると覚えましょう。

private(set)

プロパティに関しては外から変えられたくないが参照はできるというものもあります。
readonlyプロパティなどと言ったりします。
このときのアクセス修飾子はprivate(set)を使用します。

以下実装例です。

class MyClass {
    private(set) var readOnlyProperty = 0

    func testMethod() {
        let tmp = self.readOnlyProperty // OK
        self.readOnlyProperty = 1 // OK
    }
}

let myClass = MyClass()
let tmp = myClass.readOnlyProperty // OK
myClass.readOnlyProperty = 1 // NG

myClass.readOnlyProperty = 1とすると
Cannot assign to property: 'readOnlyProperty' setter is inaccessible
と怒られます。

最後に

今回はカプセル化を実現するためのアクセス修飾子について紹介しました。
それほど難しい内容ではないかなと思うのでこの機会に覚えておきましょう。
もちろんどれを公開してどれを非公開にするかの判断には多少の経験がいるかとは思いますが。

今回の内容は以上です。
本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載は以下にまとめていますのでそちらも是非もご覧ください。
http://naoyalog.com/