はじめに
Kotlin ではクラスやメンバーを宣言するとき、Java と異なるデフォルト挙動を持っています。
デフォルトは final(継承禁止) であり、継承やオーバーライドを許可する場合に open を明示する必要があります。
1. final とは?
final は「それ以上の拡張を禁止する」という意味です。
- クラスに付けると → 継承できなくなる
- メソッドやプロパティに付けると → オーバーライドできなくなる
Kotlin のクラスは デフォルトで final なので、明示的に書かなくても継承不可です。
class Animal {
fun speak() {
println("動物が鳴く")
}
}
// class Dog : Animal() { } // エラー: Animal は継承できない
2. open とは?
open は「拡張を許可する」という意味です。
クラスやメンバーを継承・オーバーライド可能にするには open を付けます。
open class Animal {
open fun speak() {
println("動物が鳴く")
}
}
class Dog : Animal() {
override fun speak() {
println("ワンワン!")
}
}
val dog = Dog()
dog.speak() // ワンワン!
Java ではクラスはデフォルトで open ですが、Kotlin は逆に デフォルトで final。
これは 安全性と明示性を重視した設計です。
3. final と open の組み合わせ
クラスは final がデフォルト
class A // final
open class B // open
メンバーは final がデフォルト
open class Base {
fun foo() {} // final → オーバーライド不可
open fun bar() {} // open → オーバーライド可能
}
override はデフォルトで open
open class Parent {
open fun speak() {}
}
class Child : Parent() {
override fun speak() {} // デフォルトで open(さらに override 可能)
}
class GrandChild : Child() {
override fun speak() {} // オーバーライド可能
}
ただし、明示的に final を付ければ「これ以上のオーバーライド禁止」になります。
class Child : Parent() {
final override fun speak() {} // 以降はオーバーライド不可
}
4. abstract と open
-
abstractは 必ずサブクラスでオーバーライドしなければならない -
abstractメンバーは暗黙的にopen -
openは「オーバーライドできる」だけで、必須ではない
abstract class Shape {
abstract fun draw() // 実装必須
}
class Circle : Shape() {
override fun draw() = println("円を描く")
}
まとめ
- Kotlin のクラスとメンバーはデフォルトで
final - 継承やオーバーライドを許可するには
openを明示する必要がある -
overrideは暗黙的にopen→ さらにfinalを付ければ制御可能 -
abstractは暗黙的にopenであり、実装を強制する