Ce face interface
O interfață este un contract: spune ce metode și proprietăți are un tip, iar clasele care o implementează scriu codul. Clasa o declară după : (class Card : MetodaPlata) și scrie fiecare membru abstract cu override. Codul care primește o MetodaPlata funcționează cu orice clasă care o implementează.
Spre deosebire de o clasă, o interfață nu poate ține stare (câmpuri cu valori), dar poate avea metode cu implementare implicită și proprietăți declarate (abstracte sau cu get()). O clasă poate implementa oricâte interfețe, dar poate moșteni o singură clasă.
fun interface (interfață funcțională, Kotlin 1.4+) are o singură metodă abstractă și poate fi creată direct dintr-o lambda: val pozitiv = Regula { it > 0 } (conversie SAM).
Exemple
Exemplul 1: O interfață, mai multe implementări
plateste primește o listă de MetodaPlata și nu știe ce clasă concretă are fiecare. descriere() are o implementare implicită, suprascrisă doar de Card.
interface MetodaPlata {
val nume: String
fun comision(suma: Double): Double
fun descriere() = "Plată prin $nume"
}
class Card(val ultimeleCifre: String) : MetodaPlata {
override val nume = "card"
override fun comision(suma: Double) = suma * 0.015
override fun descriere() = "Card care se termină în $ultimeleCifre"
}
class Numerar : MetodaPlata {
override val nume = "numerar"
override fun comision(suma: Double) = 0.0
}
fun main() {
val metode = listOf(Card("4321"), Numerar())
for (m in metode) {
println("${m.descriere()}: comision ${m.comision(200.0)} lei")
}
}
Rezultat
Card care se termină în 4321: comision 3.0 lei
Plată prin numerar: comision 0.0 lei
Exemplul 2: O clasă care implementează două interfețe
Telefon este și Incarcabil, și Conectabil, deci poate fi dat ambelor funcții și poate sta într-o listă de Conectabil.
interface Incarcabil { fun incarca(procent: Int): String }
interface Conectabil { val retea: String; fun conecteaza() = "Conectat la $retea" }
class Telefon(override val retea: String) : Incarcabil, Conectabil {
override fun incarca(procent: Int) = "Bateria este la $procent%"
}
fun laPriza(d: Incarcabil) = println(d.incarca(100))
fun peWifi(d: Conectabil) = println(d.conecteaza())
fun main() {
val t = Telefon("Acasa-5G")
laPriza(t)
peWifi(t)
val dispozitive: List<Conectabil> = listOf(t, Telefon("Birou"))
println("Rețele: ${dispozitive.map { it.retea }}")
}
Rezultat
Bateria este la 100%
Conectat la Acasa-5G
Rețele: [Acasa-5G, Birou]
Exemplul 3: fun interface creată dintr-o lambda
Regula are o singură metodă abstractă, deci fiecare regulă se scrie ca o lambda.
fun interface Regula {
fun verifica(parola: String): Boolean
}
fun main() {
val reguli = mapOf(
"minim 8 caractere" to Regula { it.length >= 8 },
"conține o cifră" to Regula { p -> p.any { it.isDigit() } },
"conține o majusculă" to Regula { p -> p.any { it.isUpperCase() } },
)
for (parola in listOf("ana2026", "Iasi2026!")) {
val incalcate = reguli.filterValues { !it.verifica(parola) }.keys
println("$parola: ${if (incalcate.isEmpty()) "OK" else "lipsește: $incalcate"}")
}
}
Rezultat
ana2026: lipsește: [minim 8 caractere, conține o majusculă]
Iasi2026!: OK
Greșeli frecvente
- Inițializarea unei proprietăți în interfață (
val nume = "x"): eroareproperty initializers in interfaces are prohibited. Foloseșteval nume: String get() = "x". - Uitarea lui
overridela implementare: eroare'x' hides member of supertype 'MetodaPlata' and needs an 'override' modifier. - Paranteze după numele interfeței:
class A : MetodaPlata()este greșit; interfețele nu au constructor. Parantezele se pun doar după o clasă de bază.
Comenzi înrudite
abstract: abstract marchează o clasă care nu poate fi creată direct și membri fără implementare, pe care subclasele trebuie să-i scrie.override și super: override înlocuiește o metodă sau o proprietate moștenită; super apelează versiunea din clasa de bază sau din interfață.by (delegare): by trimite implementarea unei interfețe către alt obiect (delegare de clasă) sau citirea unei proprietăți către un delegat.object: object declară o clasă cu un singur obiect (singleton) sau creează pe loc un obiect anonim care implementează o interfață.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.