Kotlinでは、デフォルトですべてのクラス、メソッド、およびプロパティはファイナル(final)です。つまり、明示的にopen修飾子を指定しない限り、継承やオーバーライドができません。
openキーワードは、クラスの継承またはメソッドのオーバーライドを許可します。これは、クラスがデフォルトで継承のために開かれているJavaとは根本的な違いです。
例:
open class Animal { open fun sayHello() { println("Animalからこんにちは!") } } class Dog : Animal() { override fun sayHello() { println("ワン!") } }
Animalクラスからopenを取り除くと、継承しようとするとコンパイルエラーになります。overrideが必須です。interfaceキーワードを使って実装され、openは必要ありません。Kotlinでは、Javaと同じようにすべてのクラスを継承できますか?
回答: いいえ、open(またはabstract)とマークされたクラスのみが継承できます。通常のクラスはファイナライズされており、継承できません。これは、コードの安全性と予測可能性を向上させるためです。
誤ったコードの例:
class Animal class Dog : Animal() // コンパイルエラー: "Animal"はファイナルです
逸話
Androidプラットフォーム向けのプロジェクトで、若い開発者がカスタムViewクラスからユーザーコンポーネントを継承しようとしたが、openを追加するのを忘れました。ビルドは失敗し、理由は明白ではなく、期限がずれました。問題はコンパイラのメッセージを注意深く読むまで発見されませんでした。
逸話
SDKの開発において、仕様で拡張可能な基本クラスが要求されましたが、openなしで宣言されていました。クライアントへの納品後、ライブラリがソースコードの変更なしでは拡張できないことが判明しました。アップデートをリリースしなければなりませんでした。
逸話
あるプロジェクトで、古いJavaコードをKotlinに移行する際、デフォルトのクラスの閉鎖性を忘れていました。モックを使用したユニットテストの大部分がコンパイルエラーになり、リリースプロセスが遅滞しました。openを一括で追加して問題が解決されました。