Kotlinの初心者向け問題2-8:クラスの継承を理解しよう
この問題を解くために必要な知識:
【レベル1の知識】
コメントの書き方、変数と定数、基本データ型、算術演算と論理演算、入力と出力、import文、配列、分岐処理(if、if~else、when)、繰り返し処理(for、while、do~while)、Null安全、スマートキャスト
【レベル2の知識】
関数の定義と呼び出し、関数の戻り値、関数のオーバーロード、ラベルとジャンプ、例外処理、クラスの定義と使用、インスタンス、コンストラクタ、プロパティ、クラスの継承、クラスの拡張
<<前の問題 | 問題集Top |
次の問題>> |
Kotlinの文法「クラスの継承」とは
ここではクラスの継承の意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。
Kotlinでは、クラスの継承を使うことでコードの再利用や拡張が容易になります。
オブジェクト指向プログラミングの重要な概念である「継承」は、プログラムの保守性や拡張性を向上させるために非常に役立ちます。
今回は、その基本的な使い方について解説します。
クラスの継承とは?
クラスの継承は、既存のクラス(親クラス、スーパークラス)の機能を新しいクラス(子クラス、サブクラス)に引き継ぐための仕組みです。
これにより、新しいクラスは親クラスが持つメソッドやプロパティをそのまま使ったり、必要に応じて変更することができます。
Kotlinでは、クラスはデフォルトで継承できないように設計されています。
つまり、クラスを継承可能にするためには、親クラスにopen
修飾子を付ける必要があります。
加えて、子クラスが親クラスのメソッドを変更(オーバーライド)する場合には、override
キーワードを使用します。
クラス継承の使用例
次に、Kotlinでクラス継承を実際にどのように実装するか、具体的な例を見ていきましょう。
// 親クラス(スーパークラス) open class Animal { open fun makeSound() { println("Animal makes a sound") } } // 子クラス(サブクラス) class Dog : Animal() { override fun makeSound() { println("Dog barks") } } fun main() { val dog = Dog() dog.makeSound() // Dog barks }
このコードでは、Animal
クラスが親クラス(スーパークラス)として定義されています。
Animal
クラスにはmakeSound()
というメソッドが定義されており、これを子クラスであるDog
クラスが継承しています。
Dog
クラスは親クラスのmakeSound()
メソッドをoverride
キーワードで上書きし、犬特有の音(”Dog barks”)を出力するように変更しています。
Kotlinでの継承のポイント
Kotlinでクラスを継承する際には、いくつかのポイントを押さえておく必要があります。
open
修飾子:クラスやメソッドを継承可能にするために使用します。open
が付いていないクラスやメソッドは、デフォルトで継承やオーバーライドができません。override
キーワード:親クラスのメソッドを上書きする際に使います。このキーワードが無いと、メソッドのオーバーライドはできません。また、親クラスのメソッドにはopen
修飾子が必要です。- 親クラスのコンストラクタ呼び出し:子クラスが親クラスを継承する際には、親クラスのコンストラクタも呼び出す必要があります。このため、親クラスに引数付きのコンストラクタがある場合、子クラスもその引数を渡してコンストラクタを呼び出す必要があります。
まとめ
Kotlinのクラス継承は、オブジェクト指向プログラミングの基本的な機能の一つであり、コードの再利用性を高めることができます。
クラスを継承することで、新しい機能を簡単に追加したり、既存の機能を変更できるため、保守性や拡張性の高いプログラムが作成可能です。
ただし、Kotlinではクラスやメソッドを明示的にopen
にしない限り、継承が許されないため、必要な場所で適切にopen
とoverride
を使うことが重要です。
Kotlin練習問題2-8_犬と猫の情報を表示するプログラム
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.Animalクラスの定義
1-1. nameプロパティの宣言と初期化(コンストラクタ)
1-2. displayInfo関数の定義(動物の名前を表示)
2.Dogクラスの定義
2-1. Animalクラスからの継承
2-2. bark関数の定義(犬の鳴き声を表示)
3.Catクラスの定義
3-1. Animalクラスからの継承
3-2. meow関数の定義(猫の鳴き声を表示)
4.main関数の定義
4-1. Dogクラスのインスタンス化
4-2. Catクラスのインスタンス化
4-3. displayInfo関数を使用して名前を表示
4-4. bark関数を使用して犬の鳴き声を表示
4-5. displayInfo関数を使用して名前を表示
4-6. meow関数を使用して猫の鳴き声を表示
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// 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
の名前を表示し、続けて鳴き声を表示します。
<<前の問題 |
問題集Top |
次の問題>> |
この問題への質問・コメント
この問題を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。