Kotlinでは、任意のクラスが1つの一次コンストラクタ(クラスの宣言で指定される)と複数の二次コンストラクタ(constructorを介して)を持つことができます。
private、protected、internal、public)を使用して、コンストラクタの可視性を隠したり制限したりできます。一次コンストラクタと二次コンストラクタの例:
open class Person(val name: String) { constructor(name: String, age: Int) : this(name) { // 二次コンストラクタ } } class Employee : Person { constructor(name: String) : super(name) // 明示的なsuperが必要 }
可視性修飾子:
class Secret private constructor() { companion object { fun create() = Secret() } } val s = Secret.create() // Ok, しかし Secret() はエラー
ニュアンス:
Kotlinでクラスを継承し、一次コンストラクタを呼び出さずに済ますことはできますか?
回答:いいえ。Kotlinでは、継承する際には親のコンストラクタのいずれかを必ず呼び出す必要があります — 一次でも二次(super()を通じて)でも。
例:
open class A(val x: Int) class B: A // エラー:Aのコンストラクタを明示的に呼び出す必要がある
物語
チームはクラスのオブジェクトを直接作成することを禁止しようとし、コンストラクタをprivateにしました。しかし、ファクトリメソッドを実装するのを忘れました。これにより、リフレクションなしではクラスをテストできなくなり、CIがブロックされました。
物語
一次コンストラクタに必須のパラメータを持つクラスを継承しましたが、継承者の宣言時にそれらを渡しませんでした。これは、長いデバッグの後、コンパイル時にのみ明らかになりました。
物語
二次コンストラクタを使用する際に、すべてのコンストラクタが一次コンストラクタを呼び出す必要があることを忘れました。その結果、オブジェクトが必要なパラメータなしで初期化され、ランタイムでNullPointerExceptionが発生しました。