【Kotlin】レッスン5-7:クラスの継承を基礎から理解しよう

一つ前のページでは静的メンバとインスタンスメンバについて学習しました。
今回は クラスの継承 について見ていきましょう。
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では「クラスの継承」という仕組みがあります。
本記事では「継承」が何なのか、その基本構文や具体例を通して、初心者の方でも理解できるように解説していきます。

クラスの継承とは何か?|意味と役割と基本構文
クラスの継承 とは既存のクラス(親クラス)の特徴や機能を新しいクラス(子クラス)が引き継ぐ仕組みです。
これにより同じような機能を持つクラスを効率的に作成できるため、コードの再利用性が向上し、開発の手間を大幅に削減できます。
Kotlinでは、open
修飾子 を用いて親クラスを定義し、コロン(:) を用いて子クラスに継承します。
クラスを継承する際の基本構文は以下の通りです。
// 親クラス(スーパークラス) open class 親クラス名 { // 親クラスの定義 // 継承させたい共通機能 } } // 子クラス(サブクラス) class 子クラス名 : 親クラス名 { // 親クラスを継承した子クラスの定義 // 子クラスの独自機能 }
これにより、子クラス側で親クラスの機能を使用する準備が出来ました。
クラスの継承の使用コード例と使用するメリット
次に上記の構文を使った具体例を見てみましょう。
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.") } } fun main(){ val dog = Dog("Rex") // インスタンス生成 dog.eat() // 親クラスのメソッドを呼び出し dog.bark() // 子クラスのメソッドを呼び出し }
このコードでは「Rex」という名前の犬を表すDog
オブジェクトを作成しています。
Dog
オブジェクトはAnimal
クラスを継承しているので、Animal
クラスののeat()
メソッドも使用できます。
継承を使うことで得られる主なメリットは以下の通りです:
- コードの再利用性向上:共通の機能を親クラスにまとめることで、子クラスで再定義する必要がなくなります。
- コードの保守性向上:親クラスを修正するだけで、関連するすべての子クラスに変更が反映されます。
- 設計の簡略化:複雑なクラスの関係を簡潔に整理できます。
まとめ|クラス継承のポイントを押さえよう
クラスの継承は、既存のクラスの機能を再利用しつつ、新しい機能や独自のふるまいを追加できる強力な仕組みです。
継承の仕組みを正しく理解し、状況に応じて親クラス・子クラスを適切に使い分けることで、コードの再利用性や保守性を高めることができます。
今回学んだポイントを活かして、より柔軟で拡張性の高いクラス設計にチャレンジしてみましょう。
練習問題|クラス継承を使って犬と猫を表現しよう

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() }
- 正解コードの解説
-
コードをブロックごとに分割して解説しますそれぞれのクラスや関数の役割について解説します。
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() }
cat.displayInfo()
とcat.meow()
:Cat
インスタンスであるcat
の名前を表示し、続けて鳴き声を表示します。val dog = Dog("ポチ")
:Dog
クラスのインスタンスを作成し、ポチ
という名前を与えます。このとき、Animal
クラスのname
プロパティがポチ
に初期化されます。val cat = Cat("タマ")
:Cat
クラスのインスタンスを作成し、タマ
という名前を与えます。このとき、Animal
クラスのname
プロパティがタマ
に初期化されます。dog.displayInfo()
とdog.bark()
:Dog
インスタンスであるdog
の名前を表示し、続けて鳴き声を表示します。
- サイト改善アンケート & ご指摘/ご質問
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などを アンケート 形式でお伺いしています。また記事の内容に関する ご指摘 や ご質問 もお待ちしています。