Geschiedenis van de vraag:
Het overschrijven van methoden is de basis van OOP, maar in Java was override aanvankelijk niet verplicht. Kotlin is een strikt getypeerde taal die het gebruik van override verplicht heeft gesteld om de duidelijkheid van de code te vergroten en om onbedoelde fouten bij overerving te vermijden.
Probleem:
Zonder expliciete vermelding van override is het gemakkelijk om een fout te maken bij het beschrijven van een interface/klasse: een typfout in de naam, het type, of de modifier. Het programma zal niet crashen, maar de verwachte override zal niet werken. Kotlin lost dit probleem grondig op.
Oplossing:
In Kotlin, om een methode te kunnen overschrijven, moet deze als open (of abstract/interface) worden gedeclareerd. Bij het overschrijven is het verplicht om override te gebruiken. Als de handtekeningen niet overeenkomen, is er een compilatiefout. Dit voorkomt de meeste klassieke bugs in Java.
Voorbeeldcode:
open class Base { open fun greet() { println("Hello!") } } class Child : Base() { override fun greet() { println("Hi!") } }
Belangrijkste kenmerken:
Kun je per ongeluk een functie overschrijven als je override vergeet?
Nee. Als je override mist, wordt de gedeclareerde methode beschouwd als een nieuwe methode van de klasse, en er zal geen override plaatsvinden - de compiler geeft een foutmelding als open aanwezig is bij de basismethode.
Voorbeeldcode:
open class A { open fun test() {} } class B : A() { fun test() {} // overschrijft niet! Net zoals test2() }
Kunnen eigen methoden een striktere zichtbaarheid hebben dan die van de ouder?
Nee. Je kunt de zichtbaarheid van de te overschrijven methode niet beperken. Bijvoorbeeld, als de basismethode public is, kan de override geen private/protected/internal zijn. De compiler zal een foutmelding geven.
Kan een override-component final zijn?
Ja! Als je verdere overrides wilt voorkomen, voeg dan final toe:
class D : Base() { final override fun greet() { //... } }
In Java:
public class Parent {void foo(){} } public class Child extends Parent {void foo(int x){} }
Een override wordt verwacht, maar in feite is het een overload. Aanroepen gaan niet naar de juiste methode.
Voordelen:
Nadelen:
In Kotlin:
open class Parent { open fun foo() {} } class Child : Parent() { override fun foo() { /*...*/ } }
Voordelen:
Nadelen: