Stałe z const
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 14 z 57.
const val deklaruje stałą kompilacyjną: wartość, która jest ustalana podczas kompilowania programu. Można jej używać na najwyższym poziomie pliku oraz wewnątrz object lub companion object, i tylko dla podstawowych typów, takich jak Int, Double i Boolean, oraz dla String:
const val MAX_PLAYERS = 4
class Lobby {
val players = mutableListOf<String>()
fun canStart() = players.size in MIN_PLAYERS..MAX_PLAYERS
companion object {
const val MIN_PLAYERS = 2
}
}Wewnątrz main:
val lobby = Lobby()
lobby.players += listOf("ada", "bo")
println(lobby.canStart())
println("${Lobby.MIN_PLAYERS}-$MAX_PLAYERS players")Wynik:
true
2-4 playersStałe zapisuje się za pomocą NAZW_Z_WIELKICH_LITER_ODDZIELONYCH_PODKREŚLENIAMI. const ma bardziej rygorystyczne wymagania niż val: wartość musi być znana bez uruchamiania jakiegokolwiek kodu, więc wywołanie funkcji ani lista nie są dozwolone. val w obiekcie również jest współdzielone i tylko do odczytu oraz może przyjmować dowolną wartość:
const val GREETING = "Hello" // literał typu String
const val TIMEOUT_MS = 30 * 1000 // obliczone na podstawie literałów
// const val START = System.nanoTime() // błąd: nie jest stałą
// const val DAYS = listOf("Mon", "Tue") // błąd: dozwolone są tylko typy podstawowe i String
object Defaults {
val DAYS = listOf("Mon", "Tue") // współdzielona wartość val tylko do odczytu
}Obiekt towarzyszący może też przechowywać wspólny, modyfikowalny stan. Każda instancja odczytuje i zmienia tę samą właściwość, co sprawdza się w przypadku liczników i pamięci podręcznych. Ta klasa przechowuje jedną instancję dla każdej nazwy, więc dwukrotne wywołanie zwraca ten sam obiekt (=== sprawdza, czy dwa odwołania wskazują na jeden obiekt):
class Tile private constructor(val name: String) {
companion object {
private val cache = mutableMapOf<String, Tile>()
val created: Int
get() = cache.size
fun of(name: String) = cache.getOrPut(name) { Tile(name) }
}
}Wewnątrz main:
val a = Tile.of("grass")
val b = Tile.of("grass")
Tile.of("water")
println(a === b)
println(Tile.created)Wynik:
true
2Na najwyższym poziomie czy w obiekcie towarzyszącym? Stała lub funkcja zdefiniowana na najwyższym poziomie należy do swojego pliku i jest używana pod swoją prostą nazwą w każdym pliku pakietu. Umieść stałą w obiekcie towarzyszącym, gdy należy do jednej klasy: wywołujący zapisują Lobby.MIN_PLAYERS, co wskazuje, skąd pochodzi wartość, a private const val pozostaje wewnątrz tej klasy.
// Limits.kt
const val MAX_UPLOAD_MB = 25 // używane wszędzie jako MAX_UPLOAD_MB
// Lobby.kt
class Lobby {
companion object {
const val MIN_PLAYERS = 2 // używane jako Lobby.MIN_PLAYERS
private const val ROOM_PREFIX = "L-" // tylko wewnątrz Lobby
}
}Wyzwanie
ŁatwyUzupełnij klasę Order(val item: String, val qty: Int). Jej obiekt towarzyszący przechowuje stałe MAX_QTY = 10 i PREFIX = "ORD", prywatny licznik następnego numeru zamówienia, współdzieloną tylko do odczytu sumę totalItems oraz obliczaną wartość count określającą liczbę utworzonych zamówień. Blok init wymaga, aby ilość mieściła się w zakresie od 1 do MAX_QTY, i używa komunikatu quantity must be 1-10 (utworzonego na podstawie stałej), następnie nadaje zamówieniu identyfikator ORD-001, ORD-002, ... i dodaje jego ilość do totalItems. label() zwraca ORD-001 tea x2.
Dostarczony kod wyświetla max per order: 10, następnie odczytuje wiersze tea 2 i wyświetla etykietę lub komunikat o błędzie, a na końcu orders: 2, items: 5. Odrzucone zamówienia nie zużywają numeru.
Twój kod umieść w pliku Order.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()
println("max per order: ${Order.MAX_QTY}")
for (line in input) {
val (item, qty) = line.split(" ")
try {
println(Order(item, qty.toInt()).label())
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
println("orders: ${Order.count}, items: ${Order.totalItems}")
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasKonstruktory główneBloki init i walidacjaKonstruktory dodatkowePodsumowanie — karta biblioteczna4Dziedziczenie
Klasy otwarte i podklasyNadpisywanie składowychsuper i konstruktoryKlasy abstrakcyjnePodsumowanie – katalog pracowników7Klasy specjalne
Klasy danychKlasy wyliczenioweHierarchie zapieczętowaneequals, hashCode, toStringPodsumowanie — śledzenie zamówień10Wzorce projektowe, część 2
Delegowanie za pomocą byWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Właściwości i hermetyzacja
Własne akcesoryModyfikatory widocznościPrywatne setterylazy i lateinitPowtórka – konto bankowe5Interfejsy
Deklarowanie interfejsówMetody domyślneWiele interfejsówInterfejsy jako typyPowtórzenie – metody płatności8Typy generyczne
Funkcje generyczneKlasy generyczneOgraniczenia typówKowariancja i kontrawariancja: in i outPodsumowanie — kolejka priorytetowa11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książek3Obiekty i obiekty towarzyszące
Deklaracje obiektówObiekty towarzysząceStałe z constWyrażenia obiektowePowtórzenie — kasa biletowaPoćwicz samodzielnie: Edytor online Kotlin