Sobes.tech
Junior

Cum este organizată moștenirea și polimorfismul în Kotlin?

sobes.tech AI

Răspuns de la AI

În Kotlin, moștenirea se realizează prin mecanisme de clase și interfețe. Clasele pot moșteni doar de la o altă clasă (moștenire simplă), dar pot implementa mai multe interfețe.

Prin default, toate clasele în Kotlin sunt 'finale', adică nu pot fi moștenite. Pentru a permite moștenirea, o clasă trebuie marcată explicit cu cuvântul cheie open.

Moștenirea claselor:

open class Shape { // Clasă de bază, marcată ca open
    open fun draw() { // Metodă ce poate fi suprascrisă
        println("Desenează o formă")
    }
}

class Circle : Shape() { // Moștenește de la Shape
    override fun draw() { // Suprascrierea metodei
        println("Desenează un cerc")
    }
}

În constructorul clasei derivate, trebuie să se apeleze explicit sau implicit constructorul clasei de bază.

Interfețe:

Interfețele în Kotlin sunt similare cu cele din Java 8 și pot conține metode abstracte și metode cu implementare. Clasele pot implementa una sau mai multe interfețe.

interface Drawable {
    fun draw() // Metodă abstractă
    fun description() { // Metodă cu implementare implicită
        println("Acesta este un obiect desenabil")
    }
}

class Square : Drawable {
    override fun draw() { // Implementarea metodei abstracte
        println("Desenează un pătrat")
    }
    // description() poate fi suprascris, dar nu este obligatoriu
}

Polimorfism:

Polimorfismul în Kotlin se realizează prin posibilitatea de a lucra cu obiecte din clase diferite printr-un tip de bază comun (clasă sau interfață). Acest lucru permite apelarea metodelor specifice tipului real al obiectului în timpul execuției.

fun render(drawable: Drawable) {
    drawable.draw() // Apelul metodei draw() în funcție de tipul real al obiectului
    drawable.description()
}

fun main() {
    val circle: Shape = Circle() // Obiectul Circle este tratat ca Shape
    circle.draw() // Apelul draw() din Circle datorită polimorfismului

    val square: Drawable = Square() // Obiectul Square este tratat ca Drawable
    render(square) // Apelarea draw() și description() din Square
}

În acest exemplu, render funcționează cu orice obiect care implementează Drawable. Apelul drawable.draw() va executa implementarea metodei draw pentru tipul specific al obiectului (Square în acest caz).

Diferențe între moștenirea claselor și implementarea interfețelor:

  • Moștenirea clasei: Stabilește o relație "este" (is-a). Clasa derivată moștenește starea și comportamentul clasei de bază.
  • Implementarea interfeței: Definește o "abilitate" sau un "contract". Clasa promite să furnizeze implementarea pentru toate metodele abstracte ale interfeței.

Tabel comparativ:

Caracteristică Moștenirea clasei Implementarea interfeței
Tipul relației is-a Abilitate / Contract
Multe moșteniri Unică Multiple
Stare Moștenește starea clasei de bază Nu moștenește stare
Implementarea metodelor Poate conține implementare Poate conține implementare implicită (din Java 8)