この記事で学べる知識:オーバーライド
この記事の練習問題を解くために必要な知識:
基礎文法、制御構造、メソッド、コレクション(レッスン1~4)、クラスの定義と使用、イニシャライザ、アクセスメソッド、クラス変数とクラスメソッド、privateメソッド、正規表現、クラスの継承、ファイル操作、オーバーライド、モジュールの定義と使用、ミックスイン
<<前のページ | Ruby記事一覧 |
次のページ>> |
Rubyの「オーバーライド」とは
この章ではRubyにおける「オーバーライド」の意味や使い方を学習します。用語の解説が不要な方はここをクリックして練習問題へ飛びましょう。
Rubyではオブジェクト指向プログラミングの一環として「オーバーライド」という機能が提供されています。
この機能を使うと親クラスで定義されたメソッドを子クラスで上書きして独自の動作を実装できます。
初心者にとっても、オーバーライドはクラスの柔軟性を高める重要な技術です。
オーバーライドとは?
オーバーライドとは、親クラスで定義されているメソッドを子クラスで再定義することを指します。
オーバーライドを使用することで、同じ名前のメソッドでも子クラスでは異なる振る舞いを実装できます。これによりコードの再利用性や拡張性が向上します。
Rubyでは、特にsuper
キーワードを使って親クラスのメソッドを部分的に利用することも可能です。
オーバーライドの使用例
以下はRubyでオーバーライドを行う具体的なコード例です。
# 親クラスの定義 class Animal def speak "鳴き声" end end # 子クラスの定義 class Dog < Animal # speakメソッドをオーバーライド def speak "ワンワン" end end class Cat < Animal # speakメソッドをオーバーライド def speak "ニャーニャー" end end # 使用例 dog = Dog.new puts dog.speak # => "ワンワン" cat = Cat.new puts cat.speak # => "ニャーニャー"
この例ではDog
およびCat
クラスが親クラスAnimal
のspeak
メソッドをオーバーライドしています。
このように、クラスごとに異なる動作を指定できるのがオーバーライドの強みです。
また、親クラスのメソッドを一部活用したい場合はsuper
を使います。
class Dog < Animal def speak super + "!(元気に鳴いている)" end end dog = Dog.new puts dog.speak # => "鳴き声!(元気に鳴いている)"
オーバーライドを使うメリット
オーバーライドを使用する主なメリットは以下の通りです:
- コードの再利用: 親クラスのメソッドを基に子クラス独自の動作を追加できるため、コードの重複を減らせます。
- 柔軟な拡張性: 子クラスで個別の振る舞いを定義できるため、拡張性の高いプログラムを作成できます。
- 可読性の向上: 同じ名前のメソッドを使用しつつクラスのコンテキストごとに異なる動作を定義できるため、コードが直感的になります。
まとめ
Rubyにおけるオーバーライドは、親クラスから継承したメソッドを再定義することでプログラムの柔軟性と再利用性を向上させる重要な技術です。
この機能を活用することで、より効率的で読みやすいコードを書くことができます。
次の章では、さらにオーバーライドを活用した「モジュール」の応用について学びます。
オーバーライドの練習問題
親クラスのメソッドを子クラスでオーバーライドする仕組みを学びましょう。
今回作成するコードではVehicle
クラスを親クラスとし、Car
クラスとBike
クラスを子クラスとして定義します。
親クラスに2つのメソッドを定義し、そのうち1つは子クラスでオーバーライドしましょう。
もう1つのメソッドはオーバーライドせずにそのまま利用します。これを実装してオーバーライドの挙動を理解してください。
この問題の要件
以下の要件に従ってコードを完成させてください。
- 親クラス
Vehicle
を作成し、以下のメソッドを定義してください:description
: “これは乗り物です。”と出力する。type
: “この乗り物は一般的なものです。”と出力する。
- 子クラス
Car
をVehicle
から継承して定義し、以下を実装してください:description
メソッドをオーバーライドし、super
を利用して「これは乗り物です。」の後に「 車の種類です。」を追加して出力する。
- 子クラス
Bike
をVehicle
から継承して定義し、以下を実装してください:description
メソッドを完全にオーバーライドし、「これはバイクです。」と出力する。
- 子クラス
Car
とBike
では、親クラスのtype
メソッドをそのまま使用する。 - それぞれのインスタンスを作成し、
description
とtype
メソッドを呼び出して結果を確認する。
ただし、以下のような実行結果となるコードを書くこと。
*****↓↓正解コードの実行結果の例↓↓*****
これは乗り物です。 この乗り物は一般的なものです。 これは乗り物です。 車の種類です。 この乗り物は一般的なものです。 これはバイクです。 この乗り物は一般的なものです。
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)
1:Vehicleクラスの定義
□ descriptionメソッドの定義
□ □ ”これは乗り物です。”という文字列を返す
□ typeメソッドの定義
□ □ ”この乗り物は一般的なものです。”という文字列を返す
2:Carクラスの定義(Vehicleクラスを継承)
□ 親クラスのdescriptionメソッドをオーバーライド
□ □ superを使用して親クラスのdescriptionメソッドを呼び出し、” 車の種類です。”を追加して返す
3:Bikeクラスの定義(Vehicleクラスを継承)
□ 親クラスのdescriptionメソッドをオーバーライド
□ □ ”これはバイクです。”という新しい文字列を返す
4:Vehicleクラスのインスタンスvehicleを作成
□ vehicle.descriptionメソッドを呼び出し、戻り値を出力
□ vehicle.typeメソッドを呼び出し、戻り値を出力
5:Carクラスのインスタンスcarを作成
□ car.descriptionメソッドを呼び出し、戻り値を出力
□ car.typeメソッドを呼び出し、戻り値を出力
6:Bikeクラスのインスタンスbikeを作成
□ bike.descriptionメソッドを呼び出し、戻り値を出力
□ bike.typeメソッドを呼び出し、戻り値を出力
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# 親クラス「Vehicle」を定義 class Vehicle # 乗り物の詳細を出力するメソッド def description "これは乗り物です。" end # 乗り物の種類を出力するメソッド def type "この乗り物は一般的なものです。" end end # 子クラス「Car」を定義 class Car < Vehicle =begin 【穴埋め問題1】 ここに親クラスのdescriptionメソッドをオーバーライドし、superを使って親クラスのメッセージに「 車の種類です。」を追加するコードを書いてください。 =end end # 子クラス「Bike」を定義 class Bike < Vehicle =begin 【穴埋め問題2】 ここに親クラスのdescriptionメソッドをオーバーライドし、完全に新しいメッセージ「これはバイクです。」を出力するコードを書いてください。 =end end # オブジェクトを生成し、メソッドを呼び出す vehicle = Vehicle.new puts vehicle.description # => これは乗り物です。 puts vehicle.type # => この乗り物は一般的なものです。 car = Car.new puts car.description # => これは乗り物です。 車の種類です。 puts car.type # => この乗り物は一般的なものです。 bike = Bike.new puts bike.description # => これはバイクです。 puts bike.type # => この乗り物は一般的なものです。
以上がこの問題の穴埋めコードです。
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
練習問題の解答と解説
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
# 親クラス「Vehicle」を定義 class Vehicle # 乗り物の詳細を出力するメソッド def description "これは乗り物です。" end # 乗り物の種類を出力するメソッド def type "この乗り物は一般的なものです。" end end # 子クラス「Car」を定義 class Car < Vehicle # descriptionメソッドをオーバーライド def description super + " 車の種類です。" end end # 子クラス「Bike」を定義 class Bike < Vehicle # descriptionメソッドをオーバーライド def description "これはバイクです。" end end # オブジェクトを生成し、メソッドを呼び出す vehicle = Vehicle.new puts vehicle.description # => これは乗り物です。 puts vehicle.type # => この乗り物は一般的なものです。 car = Car.new puts car.description # => これは乗り物です。 車の種類です。 puts car.type # => この乗り物は一般的なものです。 bike = Bike.new puts bike.description # => これはバイクです。 puts bike.type # => この乗り物は一般的なものです。
正解コードの解説
今回のコードはRubyのオブジェクト指向の基本であるオーバーライドの仕組みを学ぶためのものです。
親クラスに定義されたメソッドを子クラスで再定義し、新しい動作を与える方法を解説します。
クラスの定義と親クラスのメソッド
class Vehicle def description "これは乗り物です。" end def type "この乗り物は一般的なものです。" end end
class Vehicle
: 乗り物を表す親クラスを定義しています。このクラスには以下の2つのメソッドがあります。
description
: 乗り物の基本情報を出力するメソッド。type
: 「一般的な乗り物」を示すメッセージを出力するメソッド。このメソッドは子クラスでオーバーライドされません。
子クラスCar
でのオーバーライド
class Car < Vehicle def description super + " 車の種類です。" end end
class Car < Vehicle
:Vehicle
クラスを継承したCar
クラスを定義しています。これにより、Vehicle
クラスのメソッドをそのまま使ったり、オーバーライドしたりできます。description
メソッドのオーバーライド:super
: 親クラスのdescription
メソッドを呼び出しています。super
を使うことで親クラスのメッセージ「これは乗り物です。」を取得し、それに「 車の種類です。」を追加しています。
子クラスBike
でのオーバーライド
class Bike < Vehicle def description "これはバイクです。" end end
class Bike < Vehicle
:Vehicle
クラスを継承したBike
クラスを定義しています。description
メソッドの完全なオーバーライド:- 親クラスの
description
メソッドを使わず、新しいメッセージ「これはバイクです。」を出力するように再定義しています。
- 親クラスの
インスタンスの作成とメソッドの呼び出し
vehicle = Vehicle.new puts vehicle.description # => これは乗り物です。 puts vehicle.type # => この乗り物は一般的なものです。 car = Car.new puts car.description # => これは乗り物です。 車の種類です。 puts car.type # => この乗り物は一般的なものです。 bike = Bike.new puts bike.description # => これはバイクです。 puts bike.type # => この乗り物は一般的なものです。
Vehicle.new
: 親クラスのインスタンスを作成し、description
とtype
メソッドを呼び出します。Car.new
とBike.new
: 子クラスのインスタンスを作成し、それぞれのクラスで再定義されたdescription
メソッドを呼び出します。- ポイント: 親クラスから継承した
type
メソッドはオーバーライドされていないため、Car
とBike
でもそのまま利用できます。
- ポイント: 親クラスから継承した
まとめ
このコードではRubyのオブジェクト指向プログラミングにおけるオーバーライドの使い方を学びました。
- オーバーライドとは: 親クラスで定義されたメソッドを子クラスで再定義し、異なる動作をさせること。
super
の活用: 親クラスのメソッドを一部利用しながら、独自の動作を追加することが可能。- 親クラスの継承: 必要なメソッドを継承することで、コードの重複を防ぎ、柔軟性が向上します。
Rubyのクラスや継承について理解を深める第一歩として、このコードを活用してください!
<<前のページ |
Ruby記事一覧 |
次のページ>> |
この記事への質問・コメント
この記事を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。