【Kotlin】レッスン5-3:セカンダリコンストラクタの使い方と構文をマスターしよう

ながみえ

一つ前のページではプライマリコンストラクタについて学習しました。

今回は セカンダリコンストラクタ について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:関数編
Lesson4:コレクション編
Lesson5:オブジェクト指向編

 ・Lesson5-1:クラスの基本を理解しよう
 ・Lesson5-2:プライマリコンストラクタを理解しよう
 ・Lesson5-3:セカンダリコンストラクタを理解しよう ◁今回はココ
 ・Lesson5-4:ふたつのコンストラクタを使いこなそう
 ・Lesson5-5:アクセス修飾子とカプセル化を理解しよう
 ・Lesson5-6:静的メンバとインスタンスメンバを理解しよう
 ・Lesson5-7:クラスの継承を理解しよう
 ・Lesson5-8:メソッドのオーバーライドを理解しよう
 ・Lesson5-9:クラスを拡張しよう
 ・Lesson5-10:抽象クラスを理解しよう
 ・Lesson5-11:インターフェースを理解しよう
 ・Lesson5-12:データクラスを理解しよう
 ・確認問題5-☆1:モンスター捕獲ゲームを作ろう
 ・確認問題5-☆2:マルバツゲームを作ろう
 ・確認問題5-☆3:石取りゲームを作ろう

<<前のページ

学習記事一覧

次のページ>>

セカンダリコンストラクタとは?

Kotlinにはクラスの初期化方法としてプライマリコンストラクタセカンダリコンストラクタの2種類があります。

本記事では、セカンダリコンストラクタについて詳しく解説します。

これにより、複雑な初期化処理が必要な場合でも柔軟に対応できるようになります。

セカンダリコンストラクタの役割と定義方法

セカンダリコンストラクタは、プライマリコンストラクタとは異なる形でオブジェクトを初期化するための方法です。

特に、以下の場合に使用されます:

  • プライマリコンストラクタでは対応できない初期化処理が必要なとき。
  • 複数の初期化方法を用意し、オーバーロードさせたい場合

セカンダリコンストラクタを利用することで、異なる初期化パラメータや処理を柔軟に対応可能です。

あわせて読みたい
【Kotlin】レッスン3-5:関数のオーバーロードを理解しよう|引数の違いによる関数の使い分け
【Kotlin】レッスン3-5:関数のオーバーロードを理解しよう|引数の違いによる関数の使い分け

セカンダリコンストラクタは、constructorキーワード を用いて定義します。

以下は基本構文です:

class クラス名 {
    constructor(引数: 型, ...) {	// セカンダリコンストラクタの定義
        // セカンダリコンストラクタの処理
    }
}

このように、プライマリコンストラクタを定義するinitブロックとは別に定義します。

セカンダリコンストラクタの使用コード例|初期化処理のオーバーロード

セカンダリコンストラクタは、必要に応じて thisキーワード を使用して他のコンストラクタを呼び出すことができます。

以下は、セカンダリコンストラクタの実際の使用例です。

class User {
    var name: String		// 値のない変数の定義
    var age: Int			// 値のない変数の定義

    // セカンダリコンストラクタ1(引数あり)
    constructor(name: String, age: Int) {
        this.name = name	// 引数で渡された名前を設定
        this.age = age		// "この"コンストラクタのageに引数のageを代入
    }

    // セカンダリコンストラクタ2(引数なし)
    constructor() {
        this.name = "Guest"	// デフォルトの名前を設定
        this.age = 0		// "この"コンストラクタのageに0を代入
    }
}

fun main() {
    // セカンダリコンストラクタ1を使用してオブジェクトを作成
    val user1 = User("Alice", 25)
    println("User1: 名前=${user1.name}, 年齢=${user1.age}")
    
    // セカンダリコンストラクタ2を使用してオブジェクトを作成
    val user2 = User()
    println("User2: 名前=${user2.name}, 年齢=${user2.age}")
}

このコードを実行すると以下のように出力されます。

User1: 名前=Alice, 年齢=25
User2: 名前=Guest Name, 年齢=0

ふたつのセカンダリコンストラクタのどちらが使われるかは、呼び出す際の引数の数や型できまります。

この仕組みはLesson3-5で学習した オーバーロード です。

このように、セカンダリコンストラクタを利用することで、より柔軟な初期化が可能になります。

まとめ|セカンダリコンストラクタで広がる初期化のバリエーション

セカンダリコンストラクタを使うことで、同じクラスでも異なる初期化方法を柔軟に用意できるようになります。

引数の有無や内容に応じて複数のインスタンス生成パターンを実現できるので、
使いやすく再利用性の高いクラス設計が可能です。

プライマリコンストラクタと合わせて、目的や状況に応じてうまく使い分けていきましょう!

練習問題|セカンダリコンストラクタで柔軟な初期化ができる電卓を作ろう

クラスを使用して簡単な電卓プログラムを作成しましょう。

電卓クラスではセカンダリコンストラクタを使って初期値を設定します。また2種類の「add」メソッドを定義して、それぞれ1つの値と2つの値を足すことができます。

このプログラムを通じてセカンダリコンストラクタと関数のオーバーロードを習得しましょう。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. クラスの定義
    • Calculator というクラスを定義すること。
    • クラス内に整数型の変数 result を定義し、計算結果を格納すること。
  2. セカンダリコンストラクタ
    • セカンダリコンストラクタを使って Calculator を初期化し、初期値を設定すること。
  3. 関数のオーバーロード:add という名前の関数を2種類定義すること。
    • バージョン1: 1つの整数を受け取り、その値を result に加える。
    • バージョン2: 2つの整数を受け取り、その合計値を result に加える。
  4. メイン関数
    • 初期値を10として Calculator クラスをインスタンス化すること。
    • add メソッドを使って以下の計算を行うこと:
      • 値 5 を加算する。
      • 値 3 と 7 を加算する。
    • 計算結果をそれぞれ表示すること。

ただし、以下のような実行結果となること。

初期値が設定されました: 10
値 5 を加えました。現在の結果: 15
値 3 と 7 を加えました。現在の結果: 25
最終的な計算結果: 25

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:Calculatorクラスを定義
  □ 変数resultをInt型で定義し、初期値0を設定
  □ セカンダリコンストラクタを定義し、引数initialValueを受け取る
  □ □ resultにinitialValueを代入
  □ □ 初期値が設定されたことをprintlnで出力
  □ 関数addをオーバーロードし、1つ目のバージョンを定義
  □ □ 引数valueを受け取り、resultに加算
  □ □ 加算後の結果をprintlnで出力
  □ 関数addをオーバーロードし、2つ目のバージョンを定義
  □ □ 引数value1とvalue2を受け取り、それらの合計をresultに加算
  □ □ 加算後の結果をprintlnで出力
2:main関数を定義
  □ Calculatorクラスのインスタンスを生成し、初期値10を設定
  □ add関数を呼び出し、値5を加算
  □ add関数を呼び出し、値3と7を加算
  □ 最終的な計算結果をprintlnで出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

// クラスの定義
// このクラスは簡単な計算を行うツールです
class Calculator {
    var result: Int = 0 // 計算結果を格納する変数

    // セカンダリコンストラクタ
    /*【穴埋め問題1】
    ここにセカンダリコンストラクタの定義を記述してください。
    引数に初期値を取り、それをresultに代入し、初期値を出力するコードを書いてください。
    */

    // 関数のオーバーロード: 足し算を行います
    // バージョン1: 1つの値を足す
    /*【穴埋め問題2】
    ここに1つの値をresultに加算し、加算後の結果を出力するadd関数を定義してください。
    */

    // バージョン2: 2つの値を足す
    /*【穴埋め問題3】
    ここに2つの値をresultに加算し、加算後の結果を出力するadd関数を定義してください。
    */
}

fun main() {
    // Calculatorクラスのインスタンスを生成(初期値10を設定)
    val calculator = Calculator(10)

    // 1つの値を加算
    calculator.add(5)

    // 2つの値を加算
    calculator.add(3, 7)

    // 最終結果を表示
    println("最終的な計算結果: ${calculator.result}")
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

この問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
// クラスの定義
// このクラスは簡単な計算を行うツールです
class Calculator {
    var result: Int = 0 // 計算結果を格納する変数

    // セカンダリコンストラクタ
    constructor(initialValue: Int) {
        this.result = initialValue
        println("初期値が設定されました: $initialValue")
    }

    // 関数のオーバーロード: 足し算を行います
    // バージョン1: 1つの値を足す
    fun add(value: Int) {
        result += value
        println("値 $value を加えました。現在の結果: $result")
    }

    // バージョン2: 2つの値を足す
    fun add(value1: Int, value2: Int) {
        result += value1 + value2
        println("値 $value1 と $value2 を加えました。現在の結果: $result")
    }
}

fun main() {
    // Calculatorクラスのインスタンスを生成(初期値10を設定)
    val calculator = Calculator(10)

    // 1つの値を加算
    calculator.add(5)

    // 2つの値を加算
    calculator.add(3, 7)

    // 最終結果を表示
    println("最終的な計算結果: ${calculator.result}")
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

クラスの定義

class Calculator {
    var result: Int = 0 // 計算結果を格納する変数
  • class Calculator:Calculator というクラスを定義しています。クラスはオブジェクト指向プログラミングの基本単位で、関連するデータ(プロパティ)と操作(メソッド)をまとめたものです。
  • var result: Int:整数型の result をプロパティとして宣言しています。このプロパティは計算の結果を保持します。

セカンダリコンストラクタ

constructor(initialValue: Int) {
    this.result = initialValue
    println("初期値が設定されました: $initialValue")
}
  • constructor(initialValue: Int):引数 initialValue を受け取り、result プロパティに代入しています。
  • this.result = initialValue:this キーワードは、クラス内のプロパティやメソッドを指します。この場合、result プロパティに値を設定しています。
  • println():初期化が正常に行われたことをコンソールに表示します。

関数のオーバーロード

fun add(value: Int) {
    result += value
    println("値 $value を加えました。現在の結果: $result")
}

fun add(value1: Int, value2: Int) {
    result += value1 + value2
    println("値 $value1 と $value2 を加えました。現在の結果: $result")
}
  • fun add(value: Int):1つの引数を受け取り、その値を result に加えます。
  • fun add(value1: Int, value2: Int):2つの引数を受け取り、その合計を result に加えます。
  • 両方の関数で result の値を更新し、現在の計算結果をコンソールに表示します。

メイン関数

fun main() {
    val calculator = Calculator(10)
    calculator.add(5)
    calculator.add(3, 7)
    println("最終的な計算結果: ${calculator.result}")
}
  • val calculator = Calculator(10):初期値を10として Calculator クラスをインスタンス化します。このときセカンダリコンストラクタが呼び出されます。
  • calculator.add(5):引数 5 を渡し、add メソッドで1つの値を加算します。
  • calculator.add(3, 7):引数 37 を渡し、add メソッドで2つの値を加算します。
  • println():最終的な計算結果をコンソールに表示します。
Q
サイト改善アンケート & ご指摘/ご質問

本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などを アンケート 形式でお伺いしています。

また記事の内容に関する ご指摘ご質問 もお待ちしています。

1.このサイトをどのように活用していますか?また、今後どのように活用したいですか?
5.気になっているサービス・商品があれば教えてください。
※ 特定の記事に関する内容の場合は、記事番号(レッスン〇-〇)をご記入願います。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました