Menu
Coddy logo textTech

private セッター

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

多くの場合、コードの外側ではプロパティを読み取ることはあっても、変更するべきではありません。private setはゲッターを公開したまま、セッターだけをprivateにします。

class Counter {
    var count = 0
        private set

    fun increment() {
        count++
    }
}

mainの内部では:

val c = Counter()
c.increment()
println(c.count)
// c.count = 99   // エラー: セッターは private です

出力:

1

これは、正当な加算によってのみ増加するスコアのように、ルールを通じてのみ変更できる値に適しています。

class Player(val name: String) {
    var score = 0
        private set
    private val _history = mutableListOf<Int>()
    val history: List<Int> get() = _history

    fun award(points: Int) {
        if (points <= 0) return
        score += points
        _history.add(points)
    }
}

mainの内部では:

val p = Player("Ada")
p.award(10)
p.award(-5)
p.award(3)
println(p.score)
println(p.history)

出力:

13
[10, 3]

上記のhistoryは、よくあるパターンを示しています。クラス内部にプライベートなMutableListを置き、読み取り専用のListとして公開します。呼び出し側は項目を読み取れますが、項目を変更するためのaddやremoveはありません。

private val _items = mutableListOf<String>()
val items: List<String> get() = _items      // 読み取り専用ビュー
// 外側: items.add("x")                  // エラー: List には add がない

valは作成後に決して変更されず、クラスの内部であっても同じです。private setを伴うvarは、クラスの内部でのみ変更可能なままです。オブジェクトの存続期間全体を通して固定される値にはvalを選択します。

class Order(val id: Int) {            // 決して変更されない
    var status = "new"
        private set                       // 変更されるが、Order 内でのみ
    fun ship() { status = "shipped" }
}
challenge icon

チャレンジ

簡単

クラス Elevator(val topFloor: Int)を完成させてください。floorとtripsは外部から読み取れますが、クラス内部でのみ変更できます(private set)。goTo(target)はフロア0とtopFloorの間を移動します。異なるフロアへの有効な移動ではfloorを更新し、tripsに1を加えてtrueを返します。無効な移動、または同じフロアへの移動ではfalseを返します。

用意されているコードは最上階を読み取り、その後に移動先のフロアを読み取ります。移動後はfloor 3を出力し、移動が拒否された場合はstay 3を出力します。最後に、回数を付けてtrips: を出力します。

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

自分で試してみよう

fun main() {
    // 提供された入出力コード: そのままにしておく
    val input = generateSequence(::readLine).toList()
    val lift = Elevator(input[0].toInt())
    for (line in input.drop(1)) {
        val moved = lift.goTo(line.toInt())
        println("${if (moved) "floor" else "stay"} ${lift.floor}")
    }
    println("trips: ${lift.trips}")
}
quiz icon腕試し

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

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

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