In Effective Java by Joshua Bloch (Addison-Wesley, 2008), one of the best-known books on good Java programming style, recommends that you “design and document for inheritance or else prohibit it.” This means all classes and methods that aren’t specifically intended to be overridden in subclasses ought to be explicitly marked as final. Kotlin follows the same philosophy. Whereas Java’s classes and methods are open by default, Kotlin’s are final by default.
Kotlin Open Keyword
Kotlin’s “design and document for inheritance or else prohibit it” philosophy is aimed at making code more robust and less error-prone. By default, classes and methods in Kotlin are final and cannot be inherited or overridden, which means that developers must explicitly declare a class or method as open
in order to allow inheritance or overriding.
This approach differs from Java, where classes and methods are open by default, and must be explicitly marked as final
to prohibit inheritance or overriding. While this default openness in Java allows for greater flexibility and extensibility, it can also lead to potential errors and security vulnerabilities if classes or methods are unintentionally overridden or inherited.
Kotlin’s approach is designed to encourage developers to carefully consider whether inheritance or overriding is necessary for a given class or method, and to document their intentions clearly. This can help prevent unintentional errors and make code more maintainable over time.
That being said, Kotlin recognizes that there are cases where inheritance and overriding are necessary or desirable. This is why the
open
keyword exists – to explicitly allow for classes and methods to be inherited or overridden when needed. By requiring developers to explicitly declare a class or method asopen
, Kotlin ensures that these features are used deliberately and with intention.
So, in summary, Kotlin’s approach to inheritance and overriding is designed to encourage careful consideration and documentation, while still allowing for these features when needed. The open
keyword provides a way to explicitly allow for inheritance and overriding, while still maintaining Kotlin’s default “design and document for inheritance or else prohibit it” philosophy.
I hope this helps clarify why Kotlin chose to introduce the open
keyword, despite its overall philosophy of limiting inheritance and overriding by default!