Kotlinの初心者向け問題2-9:クラスの拡張を理解しよう
この問題を解くために必要な知識:
【レベル1の知識】
コメントの書き方、変数と定数、基本データ型、算術演算と論理演算、入力と出力、import文、配列、分岐処理(if、if~else、when)、繰り返し処理(for、while、do~while)、Null安全、スマートキャスト
【レベル2の知識】
関数の定義と呼び出し、関数の戻り値、関数のオーバーロード、ラベルとジャンプ、例外処理、クラスの定義と使用、インスタンス、コンストラクタ、プロパティ、クラスの継承、クラスの拡張
<<前の問題 | 問題集Top |
次の問題>> |
Kotlinの文法「クラスの拡張」とは
ここではクラスの拡張の意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。
Kotlinのクラス拡張機能を使うと、既存のクラスを変更せずに新しいメソッドやプロパティを追加することができます。
これは、オブジェクト指向プログラミングの強力な手法であり、コードの再利用性や保守性を大幅に向上させることができます。
今回は、その基本的な使い方を解説します。
クラスの拡張とは?
クラスの拡張とは、既存のクラスの振る舞いを追加・変更するための方法です。
Kotlinでは、クラス本体を修正せずに、拡張関数やプロパティを使って新しい機能をクラスに追加できます。
この機能により、ライブラリや外部コードを直接変更することなく、自分のプロジェクトに必要な機能を簡単に追加することが可能です。
たとえば、String
クラスに新しいメソッドを追加したい場合、以下のようにクラスを拡張できます。
クラス拡張の使用例
次に、String
クラスを拡張して、文字列が回文(前から読んでも後ろから読んでも同じ)かどうかを判定する新しいメソッドを追加する例を見ていきましょう。
// Stringクラスの拡張関数 fun String.isPalindrome(): Boolean { return this == this.reversed() } fun main() { val word = "racecar" println(word.isPalindrome()) // true }
このコードでは、Kotlinの標準ライブラリに含まれているString
クラスに対してisPalindrome()
という拡張関数を追加しています。
isPalindrome()
は、その文字列が回文かどうかを判断し、結果をBoolean
型で返します。
例えば、racecar
という文字列は前から読んでも後ろから読んでも同じなので、このメソッドはtrue
を返します。
Kotlinのクラス拡張の注意点
Kotlinのクラス拡張は便利ですが、いくつか注意すべき点があります。
- 既存のメソッドをオーバーライドできない:拡張関数では、既存のクラスのメソッドを上書きすることはできません。そのため、同じ名前のメソッドを定義しても、クラス本来のメソッドが優先されます。
- 静的解決:拡張関数は、クラスのインスタンスメソッドとして追加されるのではなく、あくまで静的に解決されます。これは、クラスの内部に直接追加されるわけではないということです。
まとめ
Kotlinのクラス拡張は、外部コードを変更せずに機能を追加するための非常に柔軟な方法です。
これにより、標準ライブラリや外部ライブラリのクラスに対しても、必要な機能を簡単に追加することができます。
ただし、拡張機能にはオーバーライドができないなどの制約があるため、その点を理解した上で活用することが大切です。
Kotlin練習問題2-9:車の拡張クラスを作成して車の詳細情報を表示する
Kotlinで「クラスの継承と拡張」を理解するために、車とトラックを表すプログラムを作成しましょう。
このプログラムでは、基本となるVehicle
クラスを定義し、そこからCar
クラスとTruck
クラスを継承して作成します。
それぞれのクラスに固有のプロパティやメソッドを追加することで、クラスの拡張について学びます。
この問題の要件
以下の要件に従ってプログラムを作成してください。
Vehicle
という名前のクラスを作成し、name
(名前)とspeed
(速度)という2つのプロパティを持たせること。このプロパティはコンストラクタを使用して初期化します。Vehicle
クラスに、車の名前と速度を表示するためのdisplayInfo
関数を定義すること。この関数では、name
とspeed
プロパティの値を使用して、「車の名前: [name], 速度: [speed] km/h」とコンソールに出力します。Vehicle
クラスを継承したCar
クラスを作成し、fuelType
(燃料の種類)という新しいプロパティを追加すること。このプロパティもコンストラクタを使用して初期化します。Car
クラスに、車のホーン音を表示するhonk
関数と、燃料の種類を表示するdisplayFuelType
関数を定義すること。Vehicle
クラスを継承したTruck
クラスを作成し、capacity
(積載量)という新しいプロパティを追加すること。このプロパティもコンストラクタを使用して初期化します。Truck
クラスに、トラックのホーン音を表示するhonk
関数と、積載量を表示するdisplayCapacity
関数を定義すること。main
関数を作成し、Car
クラスとTruck
クラスのインスタンスを作成して、それぞれのプロパティとメソッドを使って情報をコンソールに出力すること。
ただし、以下のような実行結果となること。
----- ↓出力される結果の例↓ -----
車の名前: フェラーリ, 速度: 300 km/h フェラーリ はビーッと鳴らしています。 フェラーリ の燃料の種類: ガソリン 車の名前: ボルボ, 速度: 100 km/h ボルボ はブォーと鳴らしています。 ボルボ の積載量: 15 トン
----- ↑出力される結果の例↑ -----
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
1.Vehicleクラスの定義
1-1. プロパティnameとspeedの宣言およびコンストラクタによる初期化
1-2. displayInfo関数の定義(車の名前と速度を表示するメソッド)
2.Carクラスの定義
2-1. Vehicleクラスの継承
2-2. プロパティfuelTypeの宣言およびコンストラクタによる初期化
2-3. honk関数の定義(車のホーン音を表示するメソッド)
2-4. displayFuelType関数の定義(燃料の種類を表示するメソッド)
3.Truckクラスの定義
3-1. Vehicleクラスの継承
3-2. プロパティcapacityの宣言およびコンストラクタによる初期化
3-3. honk関数の定義(トラックのホーン音を表示するメソッド)
3-4. displayCapacity関数の定義(積載量を表示するメソッド)
4.main関数の定義
4-1. Carクラスのインスタンス化
4-2. Truckクラスのインスタンス化
4-3. displayInfo関数を使用して車の名前と速度を表示
4-4. honk関数を使用して車のホーン音を表示
4-5. displayFuelType関数を使用して燃料の種類を表示
4-6. displayInfo関数を使用してトラックの名前と速度を表示
4-7. honk関数を使用してトラックのホーン音を表示
4-8. displayCapacity関数を使用して積載量を表示
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
// Vehicleクラスを定義 open class Vehicle(val name: String, val speed: Int) { // 名前と速度を表示する関数 fun displayInfo() { /* 【穴埋め問題1】 ここにnameとspeedプロパティを使用して、車の名前と速度を表示するコードを書いてください。 例: println("車の名前: $name, 速度: $speed km/h") */ } } // CarクラスをVehicleクラスから継承 class Car(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed) { // 車のホーン音を表示する関数 fun honk() { /* 【穴埋め問題2】 ここにnameプロパティを使用して、車のホーン音を表示するコードを書いてください。 例: println("$name はビーッと鳴らしています。") */ } // 燃料の種類を表示する関数 fun displayFuelType() { /* 【穴埋め問題3】 ここにnameとfuelTypeプロパティを使用して、燃料の種類を表示するコードを書いてください。 例: println("$name の燃料の種類: $fuelType") */ } } // TruckクラスをVehicleクラスから継承 class Truck(name: String, speed: Int, val capacity: Int) : Vehicle(name, speed) { // トラックのホーン音を表示する関数 fun honk() { /* 【穴埋め問題4】 ここにnameプロパティを使用して、トラックのホーン音を表示するコードを書いてください。 例: println("$name はブォーと鳴らしています。") */ } // 積載量を表示する関数 fun displayCapacity() { /* 【穴埋め問題5】 ここにnameとcapacityプロパティを使用して、積載量を表示するコードを書いてください。 例: println("$name の積載量: $capacity トン") */ } } fun main() { // Carクラスのインスタンスを作成 /* 【穴埋め問題6】 ここにCarクラスのインスタンスを作成するコードを書いてください。 例: val car = Car("フェラーリ", 300, "ガソリン") */ // Truckクラスのインスタンスを作成 /* 【穴埋め問題7】 ここにTruckクラスのインスタンスを作成するコードを書いてください。 例: val truck = Truck("ボルボ", 100, 15) */ // 車の名前と速度を表示 /* 【穴埋め問題8】 ここにcarインスタンスのdisplayInfo関数を呼び出すコードを書いてください。 例: car.displayInfo() */ // 車のホーン音を表示 /* 【穴埋め問題9】 ここにcarインスタンスのhonk関数を呼び出すコードを書いてください。 例: car.honk() */ // 燃料の種類を表示 /* 【穴埋め問題10】 ここにcarインスタンスのdisplayFuelType関数を呼び出すコードを書いてください。 例: car.displayFuelType() */ // トラックの名前と速度を表示 /* 【穴埋め問題11】 ここにtruckインスタンスのdisplayInfo関数を呼び出すコードを書いてください。 例: truck.displayInfo() */ // トラックのホーン音を表示 /* 【穴埋め問題12】 ここにtruckインスタンスのhonk関数を呼び出すコードを書いてください。 例: truck.honk() */ // 積載量を表示 /* 【穴埋め問題13】 ここにtruckインスタンスのdisplayCapacity関数を呼び出すコードを書いてください。 例: truck.displayCapacity() */ }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
********************
// Vehicleクラスを定義 open class Vehicle(val name: String, val speed: Int) { // 名前と速度を表示する関数 fun displayInfo() { println("車の名前: $name, 速度: $speed km/h") } } // CarクラスをVehicleクラスから継承 // クラスの拡張:Vehicleクラスに新たにfuelTypeプロパティを追加し、Carクラス固有の機能を持たせています class Car(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed) { // 車のホーン音を表示する関数 fun honk() { println("$name はビーッと鳴らしています。") } // 燃料の種類を表示する関数 // クラスの拡張:Carクラス固有のメソッド fun displayFuelType() { println("$name の燃料の種類: $fuelType") } } // TruckクラスをVehicleクラスから継承 // クラスの拡張:Vehicleクラスに新たにcapacityプロパティを追加し、Truckクラス固有の機能を持たせています class Truck(name: String, speed: Int, val capacity: Int) : Vehicle(name, speed) { // トラックのホーン音を表示する関数 fun honk() { println("$name はブォーと鳴らしています。") } // 積載量を表示する関数 // クラスの拡張:Truckクラス固有のメソッド fun displayCapacity() { println("$name の積載量: $capacity トン") } } fun main() { // Carクラスのインスタンスを作成 val car = Car("フェラーリ", 300, "ガソリン") // Truckクラスのインスタンスを作成 val truck = Truck("ボルボ", 100, 15) // 車の名前と速度を表示 car.displayInfo() // 車のホーン音を表示 car.honk() // 燃料の種類を表示 car.displayFuelType() // トラックの名前と速度を表示 truck.displayInfo() // トラックのホーン音を表示 truck.honk() // 積載量を表示 truck.displayCapacity() }
********************
コードの解説
このコードでは、Kotlinにおける「クラスの継承」と「クラスの拡張」について学びます。以下、コードの各部分を初心者向けに説明します。
Vehicle
クラスの定義
open class Vehicle(val name: String, val speed: Int) { fun displayInfo() { println("車の名前: $name, 速度: $speed km/h") } }
open class Vehicle(val name: String, val speed: Int)
:Vehicle
クラスは基本的な車両を表すクラスです。name
とspeed
という2つのプロパティを持ちます。open
キーワードは、このクラスが他のクラスから継承されることを許可します。fun displayInfo()
: この関数は、車両の名前と速度を表示します。println
関数を使って、name
とspeed
のプロパティを出力します。
Car
クラスの定義
class Car(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed) { fun honk() { println("$name はビーッと鳴らしています。") } fun displayFuelType() { println("$name の燃料の種類: $fuelType") } }
class Car(name: String, speed: Int, val fuelType: String) : Vehicle(name, speed)
:Car
クラスはVehicle
クラスを継承しています。これにより、Vehicle
クラスの機能をそのまま使用しつつ、fuelType
プロパティを追加して車の燃料タイプを管理します。fun honk()
: この関数は車のホーン音を表示します。name
プロパティを使用して、特定の車がホーンを鳴らしていることを表現します。fun displayFuelType()
: この関数は車の燃料の種類を表示します。name
とfuelType
プロパティを使用して、車の詳細を出力します。
Truck
クラスの定義
class Truck(name: String, speed: Int, val capacity: Int) : Vehicle(name, speed) { fun honk() { println("$name はブォーと鳴らしています。") } fun displayCapacity() { println("$name の積載量: $capacity トン") } }
class Truck(name: String, speed: Int, val capacity: Int) : Vehicle(name, speed)
:Truck
クラスもVehicle
クラスを継承していますが、積載量を管理するcapacity
プロパティが追加されています。fun honk()
: トラックのホーン音を表示する関数です。name
プロパティを使用して、特定のトラックがホーンを鳴らしていることを表現します。fun displayCapacity()
: この関数はトラックの積載量を表示します。name
とcapacity
プロパティを使用して、トラックの詳細を出力します。
main
関数の定義
fun main() { val car = Car("フェラーリ", 300, "ガソリン") val truck = Truck("ボルボ", 100, 15) car.displayInfo() car.honk() car.displayFuelType() truck.displayInfo() truck.honk() truck.displayCapacity() }
val car = Car("フェラーリ", 300, "ガソリン")
:Car
クラスのインスタンスを作成し、フェラーリ
という名前、300km/hの速度、ガソリンの燃料タイプを設定します。val truck = Truck("ボルボ", 100, 15)
:Truck
クラスのインスタンスを作成し、ボルボ
という名前、100km/hの速度、15トンの積載量を設定します。car.displayInfo()
とcar.honk()
とcar.displayFuelType()
:Car
クラスのインスタンスcar
の情報を表示し、ホーン音と燃料の種類を出力します。truck.displayInfo()
とtruck.honk()
とtruck.displayCapacity()
:Truck
クラスのインスタンスtruck
の情報を表示し、ホーン音と積載量を出力します。
<<前の問題 |
問題集Top |
次の問題>> |
この問題への質問・コメント
この問題を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。