【Kotlin】レッスン5-04:コンストラクタを使いこなそう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:ふたつのコンストラクタ

この記事の練習問題を解くために必要な知識:
基礎文法、制御構造、関数、コレクション(レッスン1~4)クラスの定義と使用プライマリコンストラクタセカンダリコンストラクタアクセス修飾子とカプセル化クラスメンバとインスタンスメンバクラスの継承メソッドのオーバーライドクラスの拡張抽象クラスインターフェースデータクラス

<<前のページ Kotlin記事一覧 次のページ>>

ふたつのコンストラクタの復習

ここではふたつのコンストラクタの意味や使い方を学習します。必要ない方はここをクリックして練習問題へ飛びましょう。



Kotlinにおけるコンストラクタは、クラスのインスタンスを作成する際に初期化を行う特別な仕組みです。

コンストラクタには「プライマリコンストラクタ」と「セカンダリコンストラクタ」という2種類があり、それぞれ異なる特徴と用途を持ちます。

本記事では、それぞれの構文や使い方を簡単に振り返り、両者の違いを比較してみましょう。

【初心者向け】Kotlinのオブジェクト指向を分かりやすくまとめた概念図。 特にクラスの継承、オーバーライド、抽象クラス、インターフェース、データクラスの関係性を視覚的に理解できるようまとめている。

プライマリコンストラクタの特徴

プライマリコンストラクタは、クラス名に直接付随して定義されるシンプルなコンストラクタです。

次の例を見てみましょう。

class User(val name: String, val age: Int)

上記の例ではUserクラスにプライマリコンストラクタが定義されています。

この構文ではコンストラクタの引数nameageを使ってクラスのプロパティを直接初期化しています。

  • シンプルで簡潔に記述可能
  • 初期化処理をinitブロックで追加可能

例としてinitブロックを使った初期化も紹介します。

class User(val name: String, val age: Int) {
    init {
        println("User created: $name, $age")
    }
}

ここではインスタンス生成時に自動でメッセージを出力する処理を行っています。

セカンダリコンストラクタの特徴

セカンダリコンストラクタは、constructorキーワードを使ってクラス本体内に定義されるコンストラクタです。

複雑な初期化処理が必要な場合に役立ちます。

class User {
    var name: String
    var age: Int

    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}
  • より柔軟な初期化処理が可能
  • 既存のプライマリコンストラクタを呼び出すことも可能

既存のプライマリコンストラクタを呼び出す例を見てみましょう。

class User(val name: String, val age: Int) {
    constructor(name: String) : this(name, 0)
}

この場合、名前のみを指定してインスタンスを作成するとageはデフォルトで0に設定されます。

プライマリコンストラクタとセカンダリコンストラクタの違いを比較

プライマリコンストラクタ セカンダリコンストラクタ
構文のシンプルさ 簡潔 少し冗長
柔軟性 限定的 高い
主な用途 プロパティの簡単な初期化 複雑な初期化処理
  • プライマリコンストラクタ:単純なプロパティの初期化が必要な場合に最適。
  • セカンダリコンストラクタ:初期化ロジックが複雑な場合や、異なる方法でインスタンスを生成したい場合に使用。

まとめ

コンストラクタは、Kotlinでクラスを使用する上で欠かせない機能です。

プライマリコンストラクタとセカンダリコンストラクタの違いを理解することで、シンプルで効果的なコードを書くことができます。

次回は、アクセス修飾子を活用したカプセル化について学んでいきましょう。

ふたつのコンストラクタの練習問題

「プライマリコンストラクタ」と「セカンダリコンストラクタ」を使用して、インスタンス生成とプロパティの初期化を学ぶプログラムを作成しましょう。

このプログラムではPersonクラスを用いて名前と年齢を設定する方法を体験し、さらに趣味を追加するセカンダリコンストラクタの使い方を確認します。

この問題の要件

以下の要件に従ってプログラムを作成してください。

  1. Personクラスを定義すること。
    • プライマリコンストラクタで名前 (name) と年齢 (age) を受け取り、それをプロパティとして保持すること。
    • 初期化ブロック (init) で、インスタンス生成時に名前と年齢を表示すること。
  2. Personクラスにセカンダリコンストラクタを追加すること。
    • 名前と年齢に加え、趣味 (hobby) を受け取るコンストラクタを作成すること。
    • セカンダリコンストラクタ内で趣味を設定し、それを表示すること。
  3. showInfo関数を定義し、名前、年齢、趣味を出力すること。
  4. main関数内で以下を行うこと。
    • プライマリコンストラクタを使ってインスタンスを生成し、showInfoを呼び出して情報を表示すること。
    • セカンダリコンストラクタを使ってインスタンスを生成し、showInfoを呼び出して情報を表示すること。

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

----- ↓出力される結果の例↓ -----

初期化: 太郎 さんの年齢は 25 歳です。
名前: 太郎, 年齢: 25, 趣味: 不明
初期化: 花子 さんの年齢は 30 歳です。
趣味が登録されました: 趣味は 読書 です。
名前: 花子, 年齢: 30, 趣味: 読書

この問題を解くヒント

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

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

正解のコードは上から順に以下のような構成となっています。

1:Personクラスの定義
  □ nameとageを引数とするプライマリコンストラクタを定義
  □ 変数hobbyを初期値”不明”で定義
  □ initブロックにて初期化処理を実行
  □ □ nameとageを出力する
  □ セカンダリコンストラクタを定義
  □ □ プライマリコンストラクタを呼び出し、hobbyを設定
  □ □ hobbyを出力する
  □ showInfo関数を定義
  □ □ name, age, hobbyを出力する
2:main関数の定義
  □ Personクラスのインスタンスperson1をプライマリコンストラクタで生成
  □ person1の情報を表示
  □ Personクラスのインスタンスperson2をセカンダリコンストラクタで生成
  □ person2の情報を表示

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

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

// Person クラスの定義
// このクラスではプライマリコンストラクタとセカンダリコンストラクタを使用します。
class Person(/*【穴埋め問題1】ここにプライマリコンストラクタの引数を定義してください*/) { 
    var hobby: String = "不明" // 趣味のデフォルト値

    // 初期化ブロック。インスタンス生成時に実行されます。
    init {
        println("初期化: $name さんの年齢は $age 歳です。")
    }

    // セカンダリコンストラクタ
    /*【穴埋め問題2】ここにセカンダリコンストラクタを定義し、hobbyを設定するコードを書いてください*/

    // Personの情報を表示するメソッド
    fun showInfo() {
        println("名前: $name, 年齢: $age, 趣味: $hobby")
    }
}

// メイン関数
fun main() {
    // プライマリコンストラクタを使ってインスタンスを作成
    /*【穴埋め問題3】ここにプライマリコンストラクタを使ってインスタンスを作成するコードを書いてください*/
    person1.showInfo() // 情報を表示

    // セカンダリコンストラクタを使ってインスタンスを作成
    /*【穴埋め問題4】ここにセカンダリコンストラクタを使ってインスタンスを作成するコードを書いてください*/
    person2.showInfo() // 情報を表示
}

この問題の穴埋めコードは以上です。

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

練習問題の解答と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

// Person クラスの定義
// このクラスではプライマリコンストラクタとセカンダリコンストラクタを使用します。
class Person(val name: String, val age: Int) { // プライマリコンストラクタ
    var hobby: String = "不明" // 趣味のデフォルト値

    // 初期化ブロック。インスタンス生成時に実行されます。
    init {
        println("初期化: $name さんの年齢は $age 歳です。")
    }

    // セカンダリコンストラクタ
    constructor(name: String, age: Int, hobby: String) : this(name, age) {
        this.hobby = hobby
        println("趣味が登録されました: 趣味は $hobby です。")
    }

    // Personの情報を表示するメソッド
    fun showInfo() {
        println("名前: $name, 年齢: $age, 趣味: $hobby")
    }
}

// メイン関数
fun main() {
    // プライマリコンストラクタを使ってインスタンスを作成
    val person1 = Person("太郎", 25)
    person1.showInfo() // 情報を表示

    // セカンダリコンストラクタを使ってインスタンスを作成
    val person2 = Person("花子", 30, "読書")
    person2.showInfo() // 情報を表示
}

正解コードの解説

このプログラムではKotlinの「プライマリコンストラクタ」と「セカンダリコンストラクタ」を用いて、クラスの初期化やデータの設定方法を学びます。

それぞれのコード部分について詳しく説明していきます。

クラスの定義

class Person(val name: String, val age: Int) {
    var hobby: String = "不明"
    init {
        println("初期化: $name さんの年齢は $age 歳です。")
    }
    constructor(name: String, age: Int, hobby: String) : this(name, age) {
        this.hobby = hobby
        println("趣味が登録されました: 趣味は $hobby です。")
    }
    fun showInfo() {
        println("名前: $name, 年齢: $age, 趣味: $hobby")
    }
}
  • class Person: Personクラスを定義しています。クラスはオブジェクトのテンプレートであり、属性や動作を持ちます。
  • プライマリコンストラクタ: クラス名の隣に記述されているコンストラクタです。この例では、nameageという2つのプロパティを初期化しています。
  • initブロック: インスタンス生成時に実行されるコードを記述する場所です。このコードでは、生成されたインスタンスの名前と年齢を表示しています。
  • セカンダリコンストラクタ: constructorキーワードを使って追加のコンストラクタを定義しています。このコンストラクタでは趣味 (hobby) を受け取り、thisを使ってプライマリコンストラクタを呼び出しています。

メイン関数

fun main() {
    val person1 = Person("太郎", 25)
    person1.showInfo()
    val person2 = Person("花子", 30, "読書")
    person2.showInfo()
}
  1. fun main(): Kotlinプログラムのエントリーポイントです。
  2. val person1 = Person("太郎", 25):
    • プライマリコンストラクタを使用してPersonクラスのインスタンスを作成します。
    • name"太郎", age25に設定されます。
  3. person1.showInfo():
    • メソッドshowInfoを呼び出し、インスタンスの詳細を表示します。
  4. val person2 = Person("花子", 30, "読書"):
    • セカンダリコンストラクタを使用してインスタンスを作成します。
    • hobbyとして"読書"も設定します。

まとめ

このコードではKotlinのコンストラクタを使ったクラスの初期化方法について学びました。

  • プライマリコンストラクタは、クラスの主な初期化を簡潔に記述するのに適しています。
  • セカンダリコンストラクタは、追加の初期化オプションを提供します。
  • initブロックを利用して、インスタンス生成時に初期化処理を実行することができます。

これらの特徴を理解することで、オブジェクト指向プログラミングの基礎である「クラスの設計」がより明確になります。

次回はこれらの構造を応用したプログラム作成に挑戦してみましょう!

<<前のページ Kotlin記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Kotlinテキスト&問題集へ戻る
    トップページへ戻る