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) |