【Kotlin】レッスン5-07:クラスの継承を理解しよう

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

この記事で学べる知識:クラスの継承

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

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

Kotlinの文法「クラスの継承」とは

ここではクラスの継承の意味や使い方を学習します。必要ない方はここをクリックして練習問題へ飛びましょう。



プログラムを効率よく設計・開発するために、Kotlinでは「クラスの継承」という仕組みがあります。

本記事では「継承」が何なのか、その基本構文や具体例を通して、初心者の方でも理解できるように解説していきます。

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

クラスの継承とは?

継承とは既存のクラス(親クラス)の特徴や機能を新しいクラス(子クラス)が引き継ぐ仕組みです。

これにより同じような機能を持つクラスを効率的に作成できるため、コードの再利用性が向上し、開発の手間を大幅に削減できます。

例えば動物を表す「Animal」というクラスを作成し、その性質を引き継ぐ「Dog」や「Cat」のクラスを作ることが可能です。

継承の基本構文

Kotlinでクラスを継承する際の基本構文は以下の通りです。

// 親クラス(スーパークラス)
open class Animal(val name: String) { // 親クラスとして使用するAnimalクラスの定義
    fun eat() {                       // Animalクラスのクラスメソッド
        println("$name is eating.")
    }
}

// 子クラス(サブクラス)
class Dog(name: String) : Animal(name) { // Animalクラスを継承したDogクラスの定義
    fun bark() {                         // Dogクラスのクラスメソッド
        println("$name is barking.")
    }
}
  • open修飾子:親クラスはデフォルトで継承できないため、open修飾子を使用して継承を許可します。
  • 子クラスはコロン(:)を使用して親クラスを指定します。

継承の使用例

次に上記の構文を使った具体例を見てみましょう。

fun main() {
    val myDog = Dog("Rex") // Dogクラスのインスタンスを作成
    
    myDog.eat() // 出力: Rex is eating.  // 親クラスのメソッドを使用

    myDog.bark() // 出力: Rex is barking. // 子クラス独自のメソッドを使用
}

このコードでは「Rex」という名前の犬を表すDogオブジェクトを作成しています。

このオブジェクトは、子クラスDogで定義されたbark()メソッドだけでなく、親クラスAnimaleat()メソッドも使用できます。

継承を使うメリット

継承を使うことで得られる主なメリットは以下の通りです:

  1. コードの再利用性向上:共通の機能を親クラスにまとめることで、子クラスで再定義する必要がなくなります。
  2. コードの保守性向上:親クラスを修正するだけで、関連するすべての子クラスに変更が反映されます。
  3. 設計の簡略化:複雑なクラスの関係を簡潔に整理できます。

まとめ

Kotlinの「クラスの継承」は、プログラムを効率よく設計するための強力なツールです。

この仕組みを活用することで、コードの再利用性や保守性を高めることができます。

まずは親クラスと子クラスを作成し、それぞれの役割を理解するところから始めてみましょう!

クラスの継承の練習問題

Kotlinの「クラスの継承」を理解するために、動物のクラスをベースに犬と猫のクラスを作成するプログラムを作りましょう。

このプログラムでは、動物の基本的な情報を管理するAnimalクラスを定義し、そのAnimalクラスを継承したDogクラスとCatクラスを作成します。

これにより、犬と猫の名前を表示し、それぞれの鳴き声をコンソールに表示するプログラムを完成させます。

この問題の要件

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

  • Animalという名前のクラスを作成し、nameという名前のプロパティを持たせること。このプロパティはコンストラクタを使用して初期化します。
  • Animalクラスに、動物の名前を表示するdisplayInfoという関数を作成すること。この関数では、nameプロパティの値を使用して、「動物の名前: [name]」という形でコンソールに出力します。
  • Animalクラスを継承したDogクラスを作成し、Dogクラスに犬の鳴き声を表示するbarkという関数を定義すること。この関数では、「[name] はワンワンと鳴いています。」とコンソールに出力します。
  • 同様に、Animalクラスを継承したCatクラスを作成し、Catクラスに猫の鳴き声を表示するmeowという関数を定義すること。この関数では、「[name] はニャーニャーと鳴いています。」とコンソールに出力します。
  • main関数を作成し、DogクラスとCatクラスのインスタンスを作成すること。それぞれに適切な名前を与え、displayInfo関数と鳴き声を表示する関数を呼び出して、結果をコンソールに出力すること。

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

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

動物の名前: ポチ
ポチ はワンワンと鳴いています。
動物の名前: タマ
タマ はニャーニャーと鳴いています。

この問題を解くヒント

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

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

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

1:Animalクラスの定義
  □ プライマリコンストラクタでnameプロパティを初期化
  □ displayInfoメソッドの定義
    □ 動物の名前を出力する処理
2:Dogクラスの定義(Animalクラスを継承)
  □ プライマリコンストラクタでnameプロパティを初期化
  □ barkメソッドの定義
    □ 犬の鳴き声を出力する処理
3:Catクラスの定義(Animalクラスを継承)
  □ プライマリコンストラクタでnameプロパティを初期化
  □ meowメソッドの定義
    □ 猫の鳴き声を出力する処理
4:main関数の定義
  □ Dogクラスのインスタンスを作成し、変数dogに代入
  □ Catクラスのインスタンスを作成し、変数catに代入
  □ dog.displayInfoメソッドを呼び出し、犬の名前を出力
  □ dog.barkメソッドを呼び出し、犬の鳴き声を出力
  □ cat.displayInfoメソッドを呼び出し、猫の名前を出力
  □ cat.meowメソッドを呼び出し、猫の鳴き声を出力

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

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

// Animalクラスを定義
open class Animal(val name: String) {
    // 名前を表示する関数
    fun displayInfo() {
        /* 【穴埋め問題1】
        ここにnameプロパティを使用して、動物の名前を表示するコードを書いてください。
        例: println("動物の名前: $name")
        */
    }
}

// DogクラスをAnimalクラスから継承
class Dog(name: String) : Animal(name) {
    // 犬の鳴き声を表示する関数
    fun bark() {
        /* 【穴埋め問題2】
        ここにnameプロパティを使用して、犬の鳴き声を表示するコードを書いてください。
        例: println("$name はワンワンと鳴いています。")
        */
    }
}

// CatクラスをAnimalクラスから継承
class Cat(name: String) : Animal(name) {
    // 猫の鳴き声を表示する関数
    fun meow() {
        /* 【穴埋め問題3】
        ここにnameプロパティを使用して、猫の鳴き声を表示するコードを書いてください。
        例: println("$name はニャーニャーと鳴いています。")
        */
    }
}

fun main() {
    // Dogクラスのインスタンスを作成
    /* 【穴埋め問題4】
    ここにDogクラスのインスタンスを作成するコードを書いてください。
    例: val dog = Dog("ポチ")
    */
    
    // Catクラスのインスタンスを作成
    /* 【穴埋め問題5】
    ここにCatクラスのインスタンスを作成するコードを書いてください。
    例: val cat = Cat("タマ")
    */
    
    // 犬の名前を表示
    /* 【穴埋め問題6】
    ここにdogインスタンスのdisplayInfo関数を呼び出すコードを書いてください。
    例: dog.displayInfo()
    */

    // 犬の鳴き声を表示
    /* 【穴埋め問題7】
    ここにdogインスタンスのbark関数を呼び出すコードを書いてください。
    例: dog.bark()
    */
    
    // 猫の名前を表示
    /* 【穴埋め問題8】
    ここにcatインスタンスのdisplayInfo関数を呼び出すコードを書いてください。
    例: cat.displayInfo()
    */
    
    // 猫の鳴き声を表示
    /* 【穴埋め問題9】
    ここにcatインスタンスのmeow関数を呼び出すコードを書いてください。
    例: cat.meow()
    */
}

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

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

練習問題の解答と解説

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

正解コードの例

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

// Animalクラスを定義
open class Animal(val name: String) {
    // 名前を表示する関数
    fun displayInfo() {
        println("動物の名前: $name")
    }
}

// DogクラスをAnimalクラスから継承
// クラスの継承により、Animalクラスのプロパティとメソッドを引き継ぎます
class Dog(name: String) : Animal(name) {
    // 犬の鳴き声を表示する関数
    fun bark() {
        println("$name はワンワンと鳴いています。")
    }
}

// CatクラスをAnimalクラスから継承
// Dogクラスと同様に、Animalクラスのプロパティとメソッドを引き継いでいます
class Cat(name: String) : Animal(name) {
    // 猫の鳴き声を表示する関数
    fun meow() {
        println("$name はニャーニャーと鳴いています。")
    }
}

fun main() {
    // Dogクラスのインスタンスを作成
    // Animalクラスのプロパティnameは、Dogクラスのインスタンス作成時に初期化されます
    val dog = Dog("ポチ")
    // Catクラスのインスタンスを作成
    // 同様に、Animalクラスのプロパティnameが初期化されます
    val cat = Cat("タマ")

    // 犬の名前を表示
    // 継承したdisplayInfoメソッドを使用しています
    dog.displayInfo()
    // 犬の鳴き声を表示
    dog.bark()

    // 猫の名前を表示
    // 同様に、継承したdisplayInfoメソッドを使用しています
    cat.displayInfo()
    // 猫の鳴き声を表示
    cat.meow()
}

正解コードの解説

このコードは、Kotlinで「クラスの継承」を使って、動物(Animal)クラスを基本にして犬(Dog)クラスと猫(Cat)クラスを作成する方法を学ぶためのものです。

それぞれのクラスや関数の役割について解説します。

Animalクラスの定義

open class Animal(val name: String) {
    fun displayInfo() {
        println("動物の名前: $name")
    }
}
  • open class Animal(val name: String): Animalクラスは動物を表すクラスです。nameという名前のプロパティを持ち、nameはインスタンス化されるときに初期化されます。openキーワードは、このクラスが他のクラスから継承されることを意味します。
  • fun displayInfo(): この関数は、動物の名前を表示します。println関数を使って、nameプロパティの値を出力します。

Dogクラスの定義

class Dog(name: String) : Animal(name) {
    fun bark() {
        println("$name はワンワンと鳴いています。")
    }
}
  • class Dog(name: String) : Animal(name): DogクラスはAnimalクラスを継承しています。つまり、Animalクラスのプロパティやメソッドをそのまま利用できます。nameプロパティはAnimalクラスから継承され、コンストラクタで初期化されます。
  • fun bark(): Dogクラスに特有の関数で、犬の鳴き声を出力します。nameプロパティを使用して、具体的な犬の名前と鳴き声を出力します。

Catクラスの定義

class Cat(name: String) : Animal(name) {
    fun meow() {
        println("$name はニャーニャーと鳴いています。")
    }
}
  • class Cat(name: String) : Animal(name): CatクラスもAnimalクラスを継承しています。これにより、Animalクラスのプロパティやメソッドを利用できます。
  • fun meow(): Catクラスに特有の関数で、猫の鳴き声を出力します。nameプロパティを使用して、猫の名前と鳴き声を出力します。

main関数の定義

fun main() {
    val dog = Dog("ポチ")
    val cat = Cat("タマ")
    
    dog.displayInfo()
    dog.bark()
    
    cat.displayInfo()
    cat.meow()
}
  • val dog = Dog("ポチ"): Dogクラスのインスタンスを作成し、ポチという名前を与えます。このとき、Animalクラスのnameプロパティがポチに初期化されます。
  • val cat = Cat("タマ"): Catクラスのインスタンスを作成し、タマという名前を与えます。このとき、Animalクラスのnameプロパティがタマに初期化されます。
  • dog.displayInfo()dog.bark(): Dogインスタンスであるdogの名前を表示し、続けて鳴き声を表示します。
  • cat.displayInfo()cat.meow(): Catインスタンスであるcatの名前を表示し、続けて鳴き声を表示します。
<<前のページ Kotlin記事一覧 次のページ>>

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

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

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






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