【第20章】セカンダリコンストラクタについて詳しく解説

【第20章】セカンダリコンストラクタについて詳しく解説 基礎勉強
スポンサーリンク
リンコ
リンコ

こんにちは!リンコですピヨ!この記事では自分の勉強の復習もかねて、Kotlinでのセカンダリコンストラクタを記述する方法を解説するピヨ!

この第20章では、プログラミング言語であるKotlinのセカンダリコンストラクタについて、一緒に勉強していきましょう。

この記事を読めばプログラミング未経験の方も、Kotlin入門レベルのセカンダリコンストラクタについて1つ1つ理解しながら勉強できると思うので、是非最後まで読んで頂ければと思います。

※この記事で出てくる「サンプルコード」は、記述が長く画面からはみ出ている場合がありますが、横にスライドすると表示されるのでご安心ください。

スポンサーリンク

【Kotlin】セカンダリコンストラクタについて

セカンダリコンストラクタについて

セカンダリコンストラクタはどういう時に必要なのでしょうか?セカンダリコンストラクタの記述方法を勉強する前に、どういう時に使うのか、どんなものなのかを勉強していきましょう。

※前章では、プライマリコンストラクタについても解説しているので、そちらも併せて読んで頂ければと思います。

複数のコンストラクタが必要な時に使う

プライマリコンストラクタは主要なコンストラクタという意味でしたが、セカンダリコンストラクタは主要ではない「二次的なコンストラクタ」という意味になります。

ですのでコンストラクタを使う時は、基本的にプライマリコンストラクタを使い、複数のコンストラクタが必要になる時にセカンダリコンストラクタ使うようにします。

必ず必要な記述ではない

セカンダリコンストラクタは、クラスを定義する際に絶対に必要なものではありません

プライマリコンストラクタは確実に使いますが、セカンダリコンストラクタは複数のコンストラクタが必要でなければ、使う必要はありません。

リンコ
リンコ

セカンダリコンストラクタは必ず必要なものではないピヨ!

【Kotlin】セカンダリコンストラクタを使ってみよう

セカンダリコンストラクタを使ってみよう

セカンダリコンストラクタの記述について勉強していきましょう。

セカンダリコンストラクタの書式

セカンダリコンストラクタを使う際の書式は以下のようになります。

class クラス名(var プロパティ名: 型名 = 値,var プロパティ名: 型名 = 値,...) {
  // 下記がプライマリコンストラクタのイニシャライザ
  init {
   イニシャライザブロック
  }
  // 下記がセカンダリコンストラクタ
  constructor (プロパティ名: 型名) : this(値, プロパティ名)
}

プライマリコンストラクタのイニシャライザブロックの下に記述する

セカンダリコンストラクタは、プライマリコンストラクタのイニシャライザブロックの「{}」の後に記述します。

「constructor」を省略できない

プライマリコンストラクタでは「constructor」を省略してよかったですが、セカンダリコンストラクタでは必ず「constructor」を先頭に記述する必要があるので注意しましょう。

varやvalは付けない

プライマリコンストラクタでは、引数のプロパティの部分でvarやvalをつける必要がありましたが、セカンダリコンストラクタでは付けないので、こちらも注意しましょう。

thisはプライマリコンストラクタのこと

セカンダリコンストラクタの最後の「this」は、プライマリコンストラクタのことです。

インスタンス化される際の、パラメータの値がプライマリコンストラクタと一致しなかった場合に、セカンダリコンストラクタに引き渡されます。

そしてセカンダリコンストラクタからプライマリコンストラクタに引き渡される際に、このthisが必要になります。

詳しくは、実際にコードを記述しながら解説していきます。

リンコ
リンコ

プライマリコンストラクタとセカンダリコンストラクタで記述方法が違うので注意ピヨ!

セカンダリコンストラクタを使ったコードを記述してみよう

では実際に、セカンダリコンストラクタを使ったコードを記述していきましょう。

サンプルコード

以下のサンプルコードでは、セカンダリコンストラクタで年齢だけを受け取るようなコードになっています。

fun main() {
  val rinko = Rinko(10)
}

class Rinko(val name: String, var age: Int) {
  // 下記がプライマリコンストラクタのイニシャライザ
  init {
    println("プライマリコンストラクタのイニシャライザを実行。")
    println("受け取ったパラメータは${name}と${age}です。")
  }
  // 下記がセカンダリコンストラクタ
  constructor (age: Int) : this("リンコ", age)
}

出力

サンプルコードを実行すると、以下のように出力されます。

プライマリコンストラクタのイニシャライザを実行。
受け取ったパラメータはリンコと10です。

上記では「constructor (age: Int) : this(“リンコ”, age)」の部分がセカンダリコンストラクタになります。

プライマリコンストラクタの1つ目のプロパティがString型なので、マッチしない10という整数だけをプライマリコンストラクタに指定することはできません。

ですので一度プライマリコンストラクタはスルーされ、年齢だけを指定するセカンダリコンストラクタに値が入ります。

そして年齢を、プライマリコンストラクタ(this)にそのまま引き渡します。

プライマリコンストラクタではageだけでなく、nameも受け取るように定義されているので、何らかの文字列を指定する必要がり「リンコ」という文字列を引き渡し、コードが成立しています。

【Kotlin】セカンダリコンストラクタのイニシャライザについて

セカンダリコンストラクタのイニシャライザについて

続いて、セカンダリコンストラクタでのイニシャライザについて勉強していきましょう。

プライマリコンストラクタと同じようにイニシャライザが使える

セカンダリコンストラクタでも、イニシャライザブロックを記述し、イニシャライザを使うことができます。

セカンダリコンストラクタが呼ばれた際、パラメータを受け取るだけでなく何らかの特定の処理を実行したい場合「{}」を続けて記述するようにします。

「init」を記述する必要はない

ただし、プライマリコンストラクタでは「init」を必ず記述する必要がありましたが、セカンダリコンストラクタのイニシャライザブロックの定義には「init」を記述する必要はありません

「init」は記述せず「{}」を記述し、その中にコードを記述するだけでいいので注意しましょう。

リンコ
リンコ

セカンダリコンストラクタのイニシャライザでは「init」は記述せず「{}」だけでオッケーピヨ!

【Kotlin】セカンダリコンストラクタのイニシャライザを使ってみよう

セカンダリコンストラクタのイニシャライザを使ってみよう

では実際に、セカンダリコンストラクタでもイニシャライザを使ってみましょう。

サンプルコード

以下のサンプルコードは基本的に先程と同じですが、セカンダリコンストラクタでもイニシャライザを使うようにしています。

fun main() {
  val rinko = Rinko(10)
}

class Rinko(val name: String, var age: Int) {
  // 下記がプライマリコンストラクタのイニシャライザ
  init {
    println("プライマリコンストラクタのイニシャライザを実行。")
    println("受け取ったパラメータは${name}と${age}です。")
  }
  // 下記がセカンダリコンストラクタ
  constructor (age: Int) : this("リンコ", age) {
    println("年齢のみを受け取ったセカンダリコンストラクタのイニシャライザを実行。")
  }
}

出力

サンプルコードを実行すると、以下のように出力されます。

プライマリコンストラクタのイニシャライザを実行。
受け取ったパラメータはリンコと10です。
年齢のみを受け取ったセカンダリコンストラクタのイニシャライザを実行。

上記の処理の順番をまとめると、以下の通りになります。

  1. セカンダリコンストラクタの呼び出し
  2. プライマリコンストラクタ(this)の呼び出し
  3. プライマリコンストラクタのイニシャライザの処理
  4. セカンダリコンストラクタのイニシャライザの処理
リンコ
リンコ

セカンダリコンストラクタを使い、クラスがインスタンス化される際の処理の順番はしっかり理解しておくピヨ!

【Kotlin】セカンダリコンストラクタは複数定義できる

セカンダリコンストラクタは複数定義できる

セカンダリコンストラクタは複数定義ます。最後に、セカンダリコンストラクタの複数定義のコードを記述していきましょう。

サンプルコード

以下のサンプルコードでは、プライマリコンストラクタの後にセカンダリコンストラクタが2つの合計3つのコンストラクタが定義されています。

またこのコードでは、2つの値を受け取って文字列の間に空白を入れ合体させ、それをthisでプライマリコンストラクタに引き渡しています。

fun main() {
  val rinko = Rinko("コト", "リンコ")
}

class Rinko(val name: String, var age: Int) {
  // 下記がプライマリコンストラクタのイニシャライザ
  init {
    println("プライマリコンストラクタのイニシャライザを実行。")
    println("受け取ったパラメータは${name}、${age}歳です。")
  }
  // 下記がセカンダリコンストラクタ
  constructor (age: Int) : this("無名", age) {
    println("年齢のみを受け取ったセカンダリコンストラクタのイニシャライザを実行。")
  }
  
  // 下記はもう1つのセカンダリコンストラクタ
  constructor (last_name: String, first_name: String) : this("$last_name $first_name" , 10) {
    println("苗字と名前を受け取るセカンダリコンストラクタのイニシャライザを実行。")
  }
}

出力

サンプルコードを実行すると、以下のように出力されます。

プライマリコンストラクタのイニシャライザを実行。
受け取ったパラメータはコト リンコ、10歳です。
苗字と名前を受け取るセカンダリコンストラクタのイニシャライザを実行。

main関数で苗字と名前を指定されているため、年齢だけをパラメータとして受け取るセカンダリコンストラクタが無視され、一切動いていないことがわかります。

このようにインスタンス生成の際に、呼ばれないセカンダリコンストラクタもあります。一方で、プライマリコンストラクタはクラスのインスタンス生成時に必ず呼び出されます。

ですので、プライマリコンストラクタにはそのクラスがインスタンス化される際に必ず処理したい共通の処理を記述し、セカンダリコンストラクタには、状況に応じて個別に必要になる処理を別途記述するようにしましょう。

リンコ
リンコ

セカンダリコンストラクタは状況によって複数定義するピヨ!

まとめ

まとめ

この記事では、プログラミング言語であるKotlinのセカンダリコンストラクタについて勉強していきましたが、いかがでしたでしょうか?今回の記事をまとめると以下のようになります。

  • セカンダリコンストラクタは必ず必要ではなく、臨機応変に使う
  • セカンダリコンストラクタでは必ず「constructor」を先頭に記述する
  • セカンダリコンストラクタのイニシャライザでは「init」を記述しない
  • セカンダリコンストラクタは複数定義できる

今回勉強した「セカンダリコンストラクタ」はKotlinの入門レベルの知識になるので、何回も読み直してしっかり覚えておきましょう。

リンコ
リンコ

次回の記事では「クラスの継承」について勉強していくピヨ!

プログラミング未経験の方や入門レベルの方、Kotlinについて詳しくなりたい方は、また一緒に勉強するピヨ!

コメント

タイトルとURLをコピーしました