Ce face this
În interiorul unei metode, this este obiectul pe care s-a apelat metoda. De obicei nu trebuie scris (pret înseamnă this.pret), dar devine necesar când un parametru are același nume ca proprietatea: this.pret = pret. Poți folosi this și ca să returnezi obiectul curent (pentru apeluri înlănțuite) sau ca să-l dai altei funcții.
Într-o funcție de extensie sau într-o lambda cu receptor (apply, with, buildString), this este receptorul. Când sunt mai multe niveluri, this se referă la cel mai apropiat; pentru unul exterior folosești o etichetă: this@Comanda (numele clasei) sau this@apply (numele funcției).
În constructori, this(...) apelează alt constructor al aceleiași clase.
Exemple
Exemplul 1: Parametru cu același nume ca proprietatea
În schimbaPret, pret este parametrul, iar this.pret este proprietatea obiectului.
class Produs(val nume: String, var pret: Int) {
fun schimbaPret(pret: Int) {
println("Prețul pentru $nume se schimbă din ${this.pret} în $pret")
this.pret = pret
}
}
fun main() {
val lapte = Produs("Lapte", 8)
lapte.schimbaPret(9)
println("Preț nou: ${lapte.pret} lei")
}
Rezultat
Prețul pentru Lapte se schimbă din 8 în 9
Preț nou: 9 lei
Exemplul 2: return this pentru apeluri înlănțuite
Fiecare metodă returnează obiectul curent, deci apelurile se pot scrie unul după altul.
class Mesaj {
private val parti = mutableListOf<String>()
fun catre(nume: String): Mesaj { parti.add("Către: $nume"); return this }
fun subiect(text: String): Mesaj { parti.add("Subiect: $text"); return this }
fun text(t: String): Mesaj { parti.add(t); return this }
fun construieste() = parti.joinToString("\n")
}
fun main() {
val email = Mesaj()
.catre("ana@exemplu.ro")
.subiect("Ședința de luni")
.text("Ne vedem la ora 10, în sala 2.")
.construieste()
println(email)
}
Rezultat
Către: ana@exemplu.ro
Subiect: Ședința de luni
Ne vedem la ora 10, în sala 2.
Exemplul 3: this cu etichetă
În apply, this este StringBuilder-ul. this@Comanda ajunge la obiectul clasei exterioare.
class Comanda(val numar: Int, val produse: List<String>) {
fun rezumat(): String = StringBuilder().apply {
append("Comanda ")
append(this@Comanda.numar)
append(": ")
append(produse.joinToString())
append(" (${this.length} caractere până aici)")
}.toString()
}
fun main() {
println(Comanda(1024, listOf("pâine", "brânză")).rezumat())
}
Rezultat
Comanda 1024: pâine, brânză (27 caractere până aici)
Greșeli frecvente
- Scrierea
pret = pretcând parametrul are același nume: atribui parametrul lui însuși (eroare, parametrii suntval). Scriethis.pret = pret. - În lambda-urile cu receptor,
thisnu mai este obiectul clasei: înapply { }este obiectul pe care s-a apelatapply. Foloseștethis@NumeClasa. thisîntr-o funcție de nivel de sus fără receptor: nu există obiect curent, deci este eroare.
Comenzi înrudite
class: class declară o clasă: un tip nou care grupează date (proprietăți) și comportament (metode).Funcții de extensie: O funcție de extensie adaugă o metodă nouă unui tip existent (String, Int, List), fără să modifici clasa.apply: Configurează un obiect într-un bloc în care obiectul este this, apoi returnează chiar obiectul.inner class: inner marchează o clasă din interiorul alteia care ține o referință la obiectul exterior și îi poate folosi membrii.constructor și init: constructor declară un constructor secundar (sau unul primar cu modificatori); blocurile init rulează la crearea fiecărui obiect.