Menu
Coddy logo textTech

可視性修飾子

CoddyのKotlinジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 8/57。

カプセル化とは、クラスがそのデータの使われ方を制御することです。可視性修飾子によって、メンバーを見られる人が決まります。privateはクラスの外にあるすべてのものから隠すため、クラス自身のメソッドだけがアクセスする方法になります。

class Account {
    private var balance = 0

    fun deposit(amount: Int) {
        if (amount > 0) balance += amount
    }

    fun report() = "balance: $balance"
}

mainの中では:

val a = Account()
a.deposit(50)
a.deposit(-999)
println(a.report())
// a.balance = 1_000_000    // エラー: 'balance' にアクセスできません: プライベートです

出力:

balance: 50

Kotlinには4つの修飾子があります。修飾子を指定しない宣言はpublicとなり、どこからでも見える状態です。

public      // デフォルト: どこからでも可視
internal    // 同じモジュール内で可視(アプリまたはライブラリ)
protected   // クラスとそのサブクラス内で可視
private     // クラス内で可視(トップレベル宣言の場合はファイル内)

非公開のヘルパー関数により、公開インターフェースを小さく保てます。呼び出し側に見えるのはクラスが何をするかであり、どのように実装されているかではありません。

class Password(private val text: String) {
    val isStrong: Boolean
        get() = hasDigit() && text.length >= 8

    private fun hasDigit() = text.any { it.isDigit() }
}

mainの中では:

println(Password("secret123").isStrong)
println(Password("short1").isStrong)

出力:

true
false

コンストラクターのプロパティにも修飾子を付けられます。private valは、外部のコードから読み取れない値を格納します。データを隠すことで、クラスは変更をすべて確認し、ルールを守ることができます。

class Locker(private val code: String) {
    private val items = mutableListOf<String>()
    fun store(item: String, code: String): Boolean {
        if (code != this.code) return false
        items.add(item)
        return true
    }
}
challenge icon

チャレンジ

簡単

Locker(private val code: String) クラスを完成させてください。その items リストは private です。store(item, code) は、コードが一致した場合にのみアイテムを追加し、追加できたかどうかを返します。open(code) は、コードが一致した場合はアイテムを , で結合して返し(または empty を返し)、一致しない場合は wrong code を返します。

提供されているコードはロッカーのコードを読み取り、その後 put <code> <item> または open <code> のコマンドを処理します。各 put に対して stored または denied を出力し、各 open の結果を出力します。

コードは Locker.kt に記述してください。Main.kt には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

fun main() {
    // 提供された入出力コード: そのままにしておく
    val input = generateSequence(::readLine).toList()
    val locker = Locker(input[0])
    for (cmd in input.drop(1)) {
        val p = cmd.split(" ")
        if (p[0] == "put") println(if (locker.store(p[2], p[1])) "stored" else "denied")
        else println(locker.open(p[1]))
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Kotlinプレイグラウンド