Menu
Coddy logo textTech

Prywatne settery

Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 9 z 57.

Często kod zewnętrzny powinien móc odczytywać właściwość, ale nie zmieniać jej. private set pozostawia getter publiczny i sprawia, że tylko setter jest prywatny:

class Counter {
    var count = 0
        private set

    fun increment() {
        count++
    }
}

Wewnątrz main:

val c = Counter()
c.increment()
println(c.count)
// c.count = 99   // błąd: metoda ustawiająca jest prywatna

Wynik:

1

To sprawdza się w przypadku wartości, które można zmieniać wyłącznie według określonej reguły, na przykład wyniku, który może rosnąć tylko dzięki prawidłowo przyznanym punktom:

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)
    }
}

Wewnątrz main:

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

Wynik:

13
[10, 3]

Powyższy history pokazuje typowy wzorzec: prywatna MutableList wewnątrz klasy, udostępniana jako tylko do odczytu List. Wywołujący mogą odczytywać elementy, ale nie mają metod add ani remove, aby je zmieniać:

private val _items = mutableListOf<String>()
val items: List<String> get() = _items      // widok tylko do odczytu
// na zewnątrz: items.add("x")                  // błąd: List nie ma metody add

val nigdy się nie zmienia po utworzeniu, nawet wewnątrz klasy. var z private set pozostaje zmienny tylko wewnątrz klasy. Wybieraj val dla wartości, które są stałe przez cały czas istnienia obiektu:

class Order(val id: Int) {            // nigdy się nie zmienia
    var status = "new"
        private set                       // zmienia się, ale tylko wewnątrz Order
    fun ship() { status = "shipped" }
}
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasę Elevator(val topFloor: Int). Wartości floor i trips można odczytywać z zewnątrz, ale zmieniać tylko wewnątrz klasy (private set). goTo(target) przemieszcza windę między piętrem 0 a topFloor: prawidłowy ruch na inne piętro aktualizuje floor, zwiększa trips o 1 i zwraca true; nieprawidłowy ruch lub ruch na to samo piętro zwraca false.

Dostarczony kod odczytuje najwyższe piętro, a następnie docelowe piętra. Po wykonaniu ruchu wypisuje floor 3, a gdy ruch został odrzucony — stay 3. Na końcu wypisuje trips: wraz z liczbą przejazdów.

Umieść swój kod w pliku Elevator.kt. Plik Main.kt zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

fun main() {
    // Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
    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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Edytor online Kotlin