Sobes.tech
Junior

Hoe is erfenis en polymorfisme georganiseerd in Kotlin?

sobes.tech AI

Antwoord van AI

In Kotlin wordt overerving gerealiseerd via mechanismen van klassen en interfaces. Klassen kunnen slechts van één andere klasse erven (enkelvoudige overerving), maar kunnen meerdere interfaces implementeren.

Standaard zijn alle klassen in Kotlin 'final', dat wil zeggen, ze kunnen niet worden overgeërfd. Om overerving toe te staan, moet een klasse expliciet worden gemarkeerd met het sleutelwoord open.

Overerving van klassen:

open class Shape { // Basisklasse, gemarkeerd als open
    open fun draw() { // Methode die overschreven kan worden
        println("Vorm tekenen")
    }
}

class Circle : Shape() { // Overerving van Shape
    override fun draw() { // Methode overschrijven
        println("Cirkel tekenen")
    }
}

In de constructor van de afgeleide klasse moet de constructor van de basisklasse expliciet of impliciet worden aangeroepen.

Interfaces:

Interfaces in Kotlin lijken op die in Java 8 en kunnen abstracte methoden en methoden met een standaardimplementatie bevatten. Klassen kunnen één of meerdere interfaces implementeren.

interface Drawable {
    fun draw() // Abstracte methode
    fun description() { // Methode met standaardimplementatie
        println("Dit is een tekenbaar object")
    }
}

class Square : Drawable {
    override fun draw() { // Implementatie van de abstracte methode
        println("Vierkant tekenen")
    }
    // description() kan worden overschreven, maar dat is niet verplicht
}

Polymorfisme:

Polymorfisme in Kotlin wordt bereikt door de mogelijkheid om met objecten van verschillende klassen te werken via een gemeenschappelijk basistype (klasse of interface). Dit maakt het mogelijk om methoden aan te roepen die specifiek zijn voor het daadwerkelijke type van het object, tijdens de uitvoering.

fun render(drawable: Drawable) {
    drawable.draw() // Roept de draw() methode aan afhankelijk van het daadwerkelijke type
    drawable.description()
}

fun main() {
    val circle: Shape = Circle() // Object Circle wordt behandeld als Shape
    circle.draw() // Aanroep van draw() van Circle dankzij polymorfisme

    val square: Drawable = Square() // Object Square wordt behandeld als Drawable
    render(square) // Aanroep van draw() en description() van Square
}

In dit voorbeeld werkt render met elk object dat Drawable implementeert. De aanroep drawable.draw() voert de implementatie uit van de draw-methode voor het specifieke type object (Square in dit geval).

Verschil tussen klassengeerf en interface-implementatie:

  • Klassengeerf: Stelt een "is-a" relatie vast. De afgeleide klasse erft de toestand en het gedrag van de basisklasse.
  • Interface-implementatie: Definieert een "vermogen" of "contract". De klasse belooft de implementatie te leveren van alle abstracte methoden van de interface.

Vergelijkingstabel:

Eigenschap Klassengeerf Interface-implementatie
Relatietype is-a Vermogen / Contract
Meervoudig Enkelvoudig Meervoudig
Toestand Erft de toestand van de basisklasse Erft geen toestand
Methodes Kan implementatie bevatten Kan standaardimplementatie bevatten (sinds Java 8)