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

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

継承の意味と役割をわかりやすく解説
継承とは既存のクラス(親クラス)の特徴や機能を新しいクラス(子クラス)が引き継ぐ仕組みです。
これにより同じような機能を持つクラスを効率的に作成できるため、コードの再利用性が向上し、開発の手間を大幅に削減できます。
例えば動物を表す「Animal」というクラスを作成し、その性質を引き継ぐ「Dog」や「Cat」のクラスを作ることが可能です。
Kotlinにおけるクラス継承の書き方と構文
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()
メソッドだけでなく、親クラスAnimal
のeat()
メソッドも使用できます。
継承による再利用と保守性向上の利点とは
継承を使うことで得られる主なメリットは以下の通りです:
- コードの再利用性向上:共通の機能を親クラスにまとめることで、子クラスで再定義する必要がなくなります。
- コードの保守性向上:親クラスを修正するだけで、関連するすべての子クラスに変更が反映されます。
- 設計の簡略化:複雑なクラスの関係を簡潔に整理できます。
Kotlinの継承をマスターするための学びの振り返り
Kotlinの「クラスの継承」は、プログラムを効率よく設計するための強力なツールです。
この仕組みを活用することで、コードの再利用性や保守性を高めることができます。
まずは親クラスと子クラスを作成し、それぞれの役割を理解するところから始めてみましょう!
練習問題|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() }
- 正解コードの解説
-
コードをブロックごとに分割して解説しますそれぞれのクラスや関数の役割について解説します。
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
の名前を表示し、続けて鳴き声を表示します。