ProgrammingKotlin開発者

Kotlinにおけるコンストラクタの可視性と継承の詳細を説明してください:一次コンストラクタと二次コンストラクタはどのように異なるのか、継承に関するニュアンスと可視性修飾子について説明してください。コード例と典型的なエラーを示してください。

Hintsage AIアシスタントで面接を突破

回答。

Kotlinでは、任意のクラスが1つの一次コンストラクタ(クラスの宣言で指定される)と複数の二次コンストラクタconstructorを介して)を持つことができます。

  • 一次コンストラクタは、宣言の外でコードを含むことができません(ロジックはinitにあります)。
  • 二次コンストラクタは、追加の初期化オプションを実装します。
  • 親に引数なしのコンストラクタがない場合、子は明示的にそのコンストラクタを呼び出す必要があります。
  • 修飾子(privateprotectedinternalpublic)を使用して、コンストラクタの可視性を隠したり制限したりできます。

一次コンストラクタと二次コンストラクタの例:

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() はエラー

ニュアンス:

  • 一次コンストラクタを持つクラスがパラメータを持っている場合、それらのパラメータを渡さずに継承することはできません。
  • 二次コンストラクタは、間接的または直接的に一次コンストラクタを呼び出す必要があります。
  • 内部クラスは外部クラスのprivateコンストラクタにアクセスできません。

ひっかけの質問。

Kotlinでクラスを継承し、一次コンストラクタを呼び出さずに済ますことはできますか?

回答:いいえ。Kotlinでは、継承する際には親のコンストラクタのいずれかを必ず呼び出す必要があります — 一次でも二次(super()を通じて)でも。

例:

open class A(val x: Int) class B: A // エラー:Aのコンストラクタを明示的に呼び出す必要がある

このテーマの詳細を知らないことによる実際のエラーの例。


物語

チームはクラスのオブジェクトを直接作成することを禁止しようとし、コンストラクタをprivateにしました。しかし、ファクトリメソッドを実装するのを忘れました。これにより、リフレクションなしではクラスをテストできなくなり、CIがブロックされました。


物語

一次コンストラクタに必須のパラメータを持つクラスを継承しましたが、継承者の宣言時にそれらを渡しませんでした。これは、長いデバッグの後、コンパイル時にのみ明らかになりました。


物語

二次コンストラクタを使用する際に、すべてのコンストラクタが一次コンストラクタを呼び出す必要があることを忘れました。その結果、オブジェクトが必要なパラメータなしで初期化され、ランタイムでNullPointerExceptionが発生しました。