Background:
Method overriding is foundational to OOP, but in Java, override was not mandatory initially. Kotlin is a strictly typed language that introduced mandatory use of override to enhance code clarity and avoid accidental errors during inheritance.
Issue:
Without explicit indication of override, it is easy to make mistakes when defining an interface/class: typos in names, types, modifiers. The program will not crash, but the expected overriding will not happen. Kotlin addresses this issue fundamentally.
Solution:
In Kotlin, to allow a method to be overridden, it must be declared open (or abstract/interface). It is mandatory to write override for overriding. If signatures do not match — it results in a compilation error. This prevents most classical bugs in Java.
Code example:
open class Base { open fun greet() { println("Hello!") } } class Child : Base() { override fun greet() { println("Hi!") } }
Key features:
Can you accidentally override a function if you forget override?
No. If you miss override, the declared method will be considered a new method of the class, and no overriding will occur — the compiler will issue an error if open is present for the base method.
Code example:
open class A { open fun test() {} } class B : A() { fun test() {} // does not override! Similar to test2() }
Can overridden methods have a stricter visibility than their parent?
No. You cannot narrow the visibility of the overridden method. For example, if the base method is public, the override cannot be private/protected/internal. The compiler will issue an error.
Can an override component be final?
Yes! If you do not want further overriding, add final:
class D : Base() { final override fun greet() { //... } }
In Java:
public class Parent {void foo(){} } public class Child extends Parent {void foo(int x){} }
Expected an override, but in fact — it’s a method overload. Calls go to the wrong method.
Pros:
Cons:
In Kotlin:
open class Parent { open fun foo() {} } class Child : Parent() { override fun foo() { /*...*/ } }
Pros:
Cons: