Ce face class
O clasă este un șablon după care creezi obiecte. În Kotlin, proprietățile se declară cel mai des direct în constructorul primar, din paranteza de după nume: class Produs(val nume: String, var pret: Double). val face proprietatea doar de citit, var o face modificabilă. Fără val/var, parametrul este doar un argument al constructorului, nu o proprietate.
Un obiect se creează apelând clasa ca pe o funcție, fără new: val caiet = Produs("Caiet", 7.5). Proprietățile și metodele se folosesc cu punct: caiet.pret, caiet.reducere(10). Corpul clasei (acoladele) poate lipsi dacă nu ai metode.
În Kotlin clasele sunt final implicit (nu pot fi moștenite fără open) și public. O clasă obișnuită nu are toString, equals sau copy utile; pentru clase care doar țin date folosește data class.
Exemple
Exemplul 1: Clasă cu proprietăți și metode
nume nu se poate schimba (val), pret da (var). Metoda aplicaReducere modifică obiectul.
class Produs(val nume: String, var pret: Double) {
fun aplicaReducere(procent: Int) {
pret = pret * (100 - procent) / 100
}
fun eticheta() = "$nume: $pret lei"
}
fun main() {
val caiet = Produs("Caiet A4", 12.0)
println(caiet.eticheta())
caiet.aplicaReducere(25)
println(caiet.eticheta())
println("Doar numele: ${caiet.nume}")
}
Rezultat
Caiet A4: 12.0 lei
Caiet A4: 9.0 lei
Doar numele: Caiet A4
Exemplul 2: Stare privată și proprietate calculată
sold este privat, deci se schimbă doar prin metode care verifică regulile. esteGol este calculată la fiecare citire.
class ContBancar(val titular: String) {
private var sold = 0
val esteGol: Boolean get() = sold == 0
fun depune(suma: Int) {
require(suma > 0) { "Suma trebuie să fie pozitivă" }
sold += suma
}
fun retrage(suma: Int): Boolean {
if (suma > sold) return false
sold -= suma
return true
}
fun raport() = "$titular are $sold lei"
}
fun main() {
val cont = ContBancar("Ana Popescu")
println("Gol la început? ${cont.esteGol}")
cont.depune(500)
println("Retrag 200: ${cont.retrage(200)}")
println("Retrag 1000: ${cont.retrage(1000)}")
println(cont.raport())
}
Rezultat
Gol la început? true
Retrag 200: true
Retrag 1000: false
Ana Popescu are 300 lei
Exemplul 3: Două variabile, același obiect
Variabilele țin o referință la obiect. b = a nu copiază obiectul: schimbarea prin b se vede și prin a. === verifică dacă este același obiect.
class Elev(val nume: String, var nota: Int)
fun main() {
val a = Elev("Mihai", 7)
val b = a
b.nota = 9
println("a.nota = ${a.nota}")
println("a și b sunt același obiect? ${a === b}")
val c = Elev("Mihai", 9)
println("a și c sunt același obiect? ${a === c}")
println("a == c? ${a == c} (clasa obișnuită compară referințele)")
}
Rezultat
a.nota = 9
a și b sunt același obiect? true
a și c sunt același obiect? false
a == c? false (clasa obișnuită compară referințele)
Greșeli frecvente
- Scrierea lui
new Produs(...)ca în Java: în Kotlinnewnu există. - Uitarea lui
val/varîn constructor:class Produs(nume: String)nu creează proprietatea, decicaiet.numedă eroareaunresolved reference 'nume'. - Așteptarea ca
println(obiect)să afișeze proprietățile: o clasă obișnuită afișează ceva de formaProdus@1b6d3586. ScrietoString()sau foloseștedata class.
Comenzi înrudite
constructor și init: constructor declară un constructor secundar (sau unul primar cu modificatori); blocurile init rulează la crearea fiecărui obiect.data class: data class este o clasă pentru date: primește automat toString, equals, hashCode, copy și componentN.this: this înseamnă obiectul curent: obiectul pe care s-a apelat metoda sau receptorul unei funcții de extensie.get și set (getteri și setteri): get și set definesc ce se întâmplă când o proprietate este citită sau modificată; field este valoarea păstrată în spate.open și final: În Kotlin clasele și metodele sunt final implicit; open permite moștenirea sau suprascrierea, iar final o oprește din nou.object: object declară o clasă cu un singur obiect (singleton) sau creează pe loc un obiect anonim care implementează o interfață.