Ce face object
Declarația object Config { ... } creează în același timp o clasă și unicul ei obiect. Nu poți crea alte exemplare; folosești direct numele: Config.port. Obiectul se creează la prima folosire, o singură dată. Este potrivit pentru configurări, registre, funcții utilitare grupate.
Expresia object : Comparator<String> { ... } creează pe loc un obiect anonim, care poate moșteni o clasă sau implementa interfețe. Este echivalentul claselor anonime din Java. Un obiect anonim poate folosi și modifica variabilele din jurul lui.
Un object poate avea proprietăți, metode, poate moșteni și implementa interfețe, dar nu are constructor. Un object din interiorul unei clase, marcat companion, ține membrii „statici” ai clasei.
Exemple
Exemplul 1: Singleton cu stare
Contor există o singură dată, deci toate apelurile modifică aceeași valoare. Blocul init rulează la prima folosire.
object Contor {
init { println("(Contor creat)") }
private var vizite = 0
fun inregistreaza(pagina: String) {
vizite++
println("Vizita $vizite: $pagina")
}
}
fun main() {
println("Pornesc programul")
Contor.inregistreaza("/invata/kotlin/")
Contor.inregistreaza("/invata/kotlin/object/")
Contor.inregistreaza("/")
}
Rezultat
Pornesc programul
(Contor creat)
Vizita 1: /invata/kotlin/
Vizita 2: /invata/kotlin/object/
Vizita 3: /
Exemplul 2: Obiect anonim care implementează o interfață
dupaLungime este un Comparator creat pe loc, fără să declari o clasă cu nume.
fun main() {
val orase = listOf("Iași", "Constanța", "Cluj", "Brăila")
val dupaLungime = object : Comparator<String> {
override fun compare(a: String, b: String) = a.length - b.length
}
println(orase.sortedWith(dupaLungime))
val punct = object {
val x = 3
val y = 4
fun distanta() = Math.sqrt((x * x + y * y).toDouble())
}
println("Distanța: ${punct.distanta()}")
}
Rezultat
[Iași, Cluj, Brăila, Constanța]
Distanța: 5.0
Exemplul 3: object care implementează o interfață și data object
LogConsola este singurul obiect de acest tip și poate fi dat oriunde se cere un Logger. data object are toString cu numele lui.
interface Logger { fun scrie(mesaj: String) }
object LogConsola : Logger {
override fun scrie(mesaj: String) = println("[LOG] $mesaj")
}
data object Nimic
fun proceseaza(comanda: String, log: Logger) {
log.scrie("Procesez $comanda")
}
fun main() {
proceseaza("comanda 7", LogConsola)
println(Nimic)
println(LogConsola === LogConsola)
}
Rezultat
[LOG] Procesez comanda 7
Nimic
true
Greșeli frecvente
- Încercarea de a crea un exemplar:
Config()nu compilează; unobjectnu are constructor. - Stare modificabilă într-un
objectfolosit din mai multe fire: este partajată de tot programul, deci ai nevoie de sincronizare. - Confuzia dintre
object Nume(singleton) șiobject : Tip { }(obiect nou, creat la fiecare evaluare a expresiei).
Comenzi înrudite
companion object: companion object ține membrii care aparțin clasei, nu fiecărui obiect: constante, funcții de creare, contoare comune.interface: interface descrie ce poate face un obiect (metode și proprietăți), fără stare; o clasă poate implementa mai multe interfețe.data class: data class este o clasă pentru date: primește automat toString, equals, hashCode, copy și componentN.class: class declară o clasă: un tip nou care grupează date (proprietăți) și comportament (metode).sealed class și sealed interface: sealed declară o ierarhie închisă: toate subtipurile sunt cunoscute la compilare, deci when le poate verifica pe toate fără else.