【Python入門】オーバーライドで動作を自在に変更しよう【レッスン5-6】
一つ前のLessonではプロパティについて学習しました。
今回はメソッドのオーバーライドについて見ていきましょう。
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:データクラスを理解しよう
・練習問題5-1:モンスター捕獲ゲームを作ろう
・練習問題5-2:モンスターとのバトルゲームを作ろう
次のステップ:Pythonを用いたアプリ開発
メソッドのオーバーライドとは?継承関係における再定義
この章ではPythonにおける「メソッドのオーバーライド」の意味や使い方を学習します。必要ない方はここをクリックして練習問題へ飛びましょう。
メソッドのオーバーライドとは、親クラスで定義されたメソッドを子クラスで再定義する機能です。
オブジェクト指向プログラミングの重要な概念であり、親クラスのメソッドの基本的な動作を変更したい場合に使用されます。これにより、さらに柔軟なクラス設計が可能となります。
たとえば動物クラスに「鳴く」メソッドが定義されている場合、その動作を異なる動物ごとにカスタマイズすることができます。
これがメソッドのオーバーライドです。
メソッドのオーバーライドの使用例
ここでは動物のクラスを例にして、メソッドのオーバーライドを見ていきます。
親クラスで「鳴く」メソッドが定義されており、これを子クラスで上書き(オーバーライド)しています。
# 親クラスを定義 class Animal: def make_sound(self): print("動物が鳴いています") # 子クラスを定義して、親クラスのメソッドをオーバーライド class Dog(Animal): def make_sound(self): print("ワンワン!") class Cat(Animal): def make_sound(self): print("ニャーニャー") # インスタンスを作成し、メソッドを呼び出す dog = Dog() dog.make_sound() # 出力: ワンワン! cat = Cat() cat.make_sound() # 出力: ニャーニャー
この例ではAnimal
という親クラスにmake_sound
というメソッドがあり、Dog
とCat
という子クラスでそれぞれ異なる実装を行っています。
Dog
クラスでは「ワンワン!」、Cat
クラスでは「ニャーニャー」と鳴く動作にオーバーライドされています。
メソッドのオーバーライドの利点
メソッドのオーバーライドを使うことで、コードの再利用性が向上し、柔軟に動作を変更することができます。
親クラスに共通のメソッドを定義し、子クラスで必要な場合にその動作をカスタマイズすることで、無駄なコードの繰り返しを防ぎ、保守性の高いコードを書くことが可能です。
またオーバーライドによって、子クラスに特有の振る舞いを簡単に実装できるため、クラス設計がより直感的になります。
まとめ
メソッドのオーバーライドは親クラスの機能を子クラスでカスタマイズするための強力な手段です。
この機能を使うことでコードの再利用性が高まり、オブジェクト指向プログラミングの利点を活かすことができます。
練習問題:家電製品の動作をシミュレーションしよう
クラスの継承とメソッドのオーバーライドを使った家電製品のシミュレーションプログラムを作成しましょう。
親クラスで基本的な家電の操作を定義し、洗濯機と冷蔵庫の子クラスでそれぞれの動作をカスタマイズします。
問題の詳細条件
以下の要件に従ってコードを完成させてください。
- 親クラス
Appliance
を定義し、名前を設定する__init__
メソッドを作成すること。 - 親クラスで家電製品を操作する
operate
メソッドを定義すること。 WashingMachine
クラスとRefrigerator
クラスを親クラスから継承し、それぞれのoperate
メソッドをオーバーライドすること。- 各家電の操作を順に出力すること。
ただし、以下のような実行結果となるコードを書くこと。
洗濯機で洗濯を開始します 冷蔵庫で冷蔵を開始します
【ヒント】難しいと感じる人だけ見よう
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)1:親クラスApplianceの定義
□ __init__メソッドの定義
□ □ 引数nameをインスタンス変数self.nameに代入
□ operateメソッドの定義
□ □ 家電製品の操作メッセージを返す2:子クラスWashingMachineの定義
□ operateメソッドをオーバーライドして定義
□ □ 洗濯機の操作メッセージを返す3:子クラスRefrigeratorの定義
□ operateメソッドをオーバーライドして定義
□ □ 冷蔵庫の操作メッセージを返す4:家電製品のリストappliancesを作成
□ WashingMachineとRefrigeratorのインスタンスを生成し、リストに追加5:for文によるループ処理
□ 各家電製品のoperateメソッドを実行して出力
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# 親クラスの定義 class Appliance: """【穴埋め問題1】ここにApplianceクラスの初期化メソッド__init__を定義し、家電製品の名前を設定するコードを書いてください。""" """【穴埋め問題2】ここにoperateメソッドを定義し、家電製品の操作メッセージを返すコードを書いてください。""" # 子クラスの定義(洗濯機) class WashingMachine(Appliance): """【穴埋め問題3】ここにWashingMachineクラスのoperateメソッドをオーバーライドし、洗濯を開始するメッセージを返すコードを書いてください。""" # 子クラスの定義(冷蔵庫) class Refrigerator(Appliance): """【穴埋め問題4】ここにRefrigeratorクラスのoperateメソッドをオーバーライドし、冷蔵を開始するメッセージを返すコードを書いてください。""" # 家電製品のリストを作成し、それぞれの操作を出力します appliances = [WashingMachine("洗濯機"), Refrigerator("冷蔵庫")] # 各家電製品の操作を順に出力 for appliance in appliances: """【穴埋め問題5】ここに家電製品の操作メッセージを出力するコードを書いてください。"""
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
問題の答え合わせと解説
この問題の一つの正解例とそのコードの解説を以下に示します。
一つの正解例
例えば以下のようなプログラムが考えられます。
- 正解コード
-
# 親クラスの定義 class Appliance: # 初期化メソッド (__init__)、家電製品の名前を設定します def __init__(self, name): self.name = name # 親クラスのメソッド、家電製品の操作を定義します def operate(self): return f"{self.name}を操作しています" # 子クラスの定義(洗濯機) class WashingMachine(Appliance): # 親クラスのoperateメソッドをオーバーライドしています def operate(self): return f"{self.name}で洗濯を開始します" # 子クラスの定義(冷蔵庫) class Refrigerator(Appliance): # 親クラスのoperateメソッドをオーバーライドしています def operate(self): return f"{self.name}で冷蔵を開始します" # 家電製品のリストを作成し、それぞれの操作を出力します appliances = [WashingMachine("洗濯機"), Refrigerator("冷蔵庫")] # 各家電製品の操作を順に出力 for appliance in appliances: print(appliance.operate()) # 出力:洗濯機で洗濯を開始します, 冷蔵庫で冷蔵を開始します
正解例の詳細解説
正解コードをブロックごとに解説します。
- 詳細解説
-
親クラスの定義と
__init__
メソッドdef __init__(self, name): self.name = name
まず親クラス
Appliance
が定義されています。このクラスには__init__
メソッドがあり、家電製品の名前を設定します。__init__
メソッドはクラスのインスタンスを作成する際に自動的に呼び出される初期化メソッドです。たとえば
WashingMachine
やRefrigerator
を作成するときに、家電製品の名前を設定する役割を果たします。operate
メソッドdef operate(self): return f"{self.name}を操作しています"
親クラスには
operate
というメソッドもあります。このメソッドは家電製品が操作されるときの動作を定義しており、
self.name
を使って家電の名前を表示するようになっています。メソッドのオーバーライド
def operate(self): return f"{self.name}で洗濯を開始します"
def operate(self): return f"{self.name}で冷蔵を開始します"
このプログラムのポイントは「メソッドのオーバーライド」です。
メソッドのオーバーライドとは、親クラスで定義されたメソッドを子クラスで上書きすることを意味します。
ここでは
WashingMachine
とRefrigerator
という2つの子クラスが親クラスAppliance
のoperate
メソッドをオーバーライドしています。WashingMachine
クラスでは、洗濯機の動作メッセージを返すようにオーバーライドしています。Refrigerator
クラスでは、冷蔵庫の動作メッセージを返すようにオーバーライドしています。
これにより親クラスの基本動作を子クラスでカスタマイズすることが可能になります。
たとえば、
operate
メソッドは同じ名前ですが、洗濯機では「洗濯を開始」、冷蔵庫では「冷蔵を開始」という異なるメッセージを出力します。家電リストの作成と動作の出力
for appliance in appliances: print(appliance.operate())
最後に家電製品のインスタンスをリスト
appliances
に追加し、for
ループを使って各家電製品の操作を順に実行します。このループはリスト内の各家電製品に対して
operate
メソッドを呼び出し、その結果をprint
で出力します。各家電製品がオーバーライドしたメソッドを持つため、対応する操作メッセージが表示されます。
まとめ
このコードではクラスの継承とメソッドのオーバーライドの仕組みを理解できます。
メソッドのオーバーライドを使うことで、親クラスで定義された機能を子クラスで簡単にカスタマイズできることがわかりました。
これによりコードの再利用性が高まり、拡張性も向上します。
FAQ|Pythonのオーバーライドの基本
- Q1. オーバーライドと継承の違いは何ですか?
-
継承は親クラスの機能を受け継ぐ仕組みで、オーバーライドはその機能を子クラスで再定義することを指します。
- Q2. オーバーライドする際の注意点は?
-
メソッド名を完全に一致させる必要があります。また、親クラスのメソッドを維持したい場合は
super()
を活用します。
- Q3. オーバーライドはクラス間で自由にできますか?
-
同じ名前のメソッドが親クラスに存在する場合に限り、子クラスでオーバーライドが有効になります。
質問用コンタクトフォーム
この記事はAIを用いて書いた記事です。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。