【Python】レッスン5-06:メソッドのオーバーライドを理解しよう

一つ前の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基礎習得者にお勧めの道5選(実務or副業)
継承でメソッドを再定義する基礎|同じ呼び出しで違う挙動
親クラスのメソッドを子クラスで「再定義」して振る舞いを変える――それがメソッドのオーバーライドです。
詳しい書き方や注意点は本文で扱いますが、要は共通処理は親に集約し、差分だけを子で表現するための基本テクニックだと捉えてください。
この知識を身につけると、重複の少ない保守しやすい設計ができ、ライブラリやフレームワークの“フック”を扱う場面でも自信を持って対応できます。
それでは、要点→コード例→練習問題の流れで身につけていきましょう。本文へ進んで、実際に手を動かしてください。
オーバーライドとは|親クラスのメソッドを子クラスで再定義
メソッドのオーバーライドとは、親クラスで定義されたメソッドを子クラスで再定義する機能です。
オブジェクト指向プログラミングの重要な概念であり、親クラスのメソッドの基本的な動作を変更したい場合に使用されます。これにより、さらに柔軟なクラス設計が可能となります。
オーバーライドは、子クラス内で親クラスが持つものとと同名のメソッドを定義することで実施できます。
class 親クラス名: def メソッド名(): # 処理内容 class 子クラス名(親クラス名): def メソッド名(): # オーバーライド(親クラスのメソッドと同名のメソッドを定義) # 処理内容
オーバーライドの使用コード例
ここでは動物のクラスを例にして、メソッドのオーバーライドを見ていきます。
親クラスで「鳴く」メソッドが定義されており、これを子クラスで上書き(オーバーライド)しています。
class Animal: # Animalクラスを定義 def sound(self): # soundメソッドを定義 print("動物が鳴いています") class Dog(Animal): # Animalクラスを継承したDogクラスを定義 def sound_dog(self): # sound_dogメソッドを定義 print("ワンワン!") class Cat(Animal): # Animalクラスを継承したCatクラスを定義 def sound(self): # オーバーライド(親クラス内のメソッドと同名のメソッドを定義) print("ニャーニャー") dog = Dog() # インスタンス生成 dog.sound() # 親クラスのメソッドを呼び出し dog.sound_dog() # 子クラスのメソッドを呼び出し cat = Cat() # インスタンス生成 cat.sound() # soundメソッドは子クラス側でオーバーライド(上書き)されている # 出力: ニャーニャー
この例ではAnimal
という親クラスにsound
というメソッドがあり、Dog
とCat
という子クラスでそれぞれ異なる実装を行っています。
Cat
クラスのsound
メソッドは「ニャーニャー」と鳴く動作にオーバーライドされています。
このコードを実行すると、以下のように出力されます。
動物が鳴いています ワンワン! ニャーニャー
このように、メソッドのオーバーライドを使うことでコードの再利用性が向上し、柔軟に動作を変更することができます。
親クラスに共通のメソッドを定義し、子クラスで必要な場合にその動作をカスタマイズすることで、無駄なコードの繰り返しを防ぎ、保守性の高いコードを書くことが可能です。
またオーバーライドによって、子クラスに特有の振る舞いを簡単に実装できるため、クラス設計がより直感的になります。
まとめ|共通インターフェースのまま振る舞いを変えよう
継承関係にあるクラスで「同名のメソッドを再定義=オーバーライド」することで、親クラスの設計を活かしつつ、子クラスの振る舞いを置き換えたり拡張できることを学びました。
この学習によって、共通処理は親クラスに集約し、差分だけを子クラスで表現する設計ができます。
オーバーライドは、現実の要件変更にも強いクラス設計の要です。
小さなクラスでも手を動かして「再定義で何が変わるか」を確かめるほど、設計力が一段上がります。
今日学んだ手がかりを足場に、コードの表現力を少しずつ広げていきましょう。
- サイト改善アンケート|ご意見をお聞かせください(1分で終わります)
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。1分だけ、ご協力いただけますと幸いです。
【Python】サイト改善アンケート
練習問題:オーバーライドを使ってみよう
この記事で学習した「オーバーライド」を復習する練習問題に挑戦しましょう。
問題|家電製品の動作をシミュレーションしよう
クラスの継承とメソッドのオーバーライドを使った家電製品のシミュレーションプログラムを作成しましょう。
親クラスで基本的な家電の操作を定義し、洗濯機と冷蔵庫の子クラスでそれぞれの動作をカスタマイズします。
以下の要件に従ってコードを完成させてください。
- 親クラス
Appliance
を定義し、名前を設定する__init__
メソッドを作成すること。 - 親クラスで家電製品を操作する
operate
メソッドを定義すること。 WashingMachine
クラスとRefrigerator
クラスを親クラスから継承し、それぞれのoperate
メソッドをオーバーライドすること。- 各家電の操作を順に出力すること。
ただし、以下のような実行結果となるコードを書くこと。
洗濯機で洗濯を開始します 冷蔵庫で冷蔵を開始します
ヒント|難しいと感じる人だけ見よう
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
1:親クラスで「共通の状態」と「基本動作」を定義する
・共通化したい情報(名前)はインスタンス変数として保持する
・初期化処理はコンストラクタで行い、受け取った値をそのまま保存する
・基本動作は「返す」設計にして、表示は呼び出し側に任せる2:子クラスで基本動作を「上書き」して個別の挙動にする
・親クラスを継承して、初期化の仕組みはそのまま引き継ぐ
・親と同じメソッド名・引数で定義し直してオーバーライドする
・返すメッセージだけを各家電に合わせて変更し、文字列として返す3:インスタンスをリストにまとめ、同じ操作で順番に実行結果を出力する
・サブクラスのインスタンスを作り、所定の順番でリストに入れる
・繰り返し処理で各要素を取り出し、同じメソッド名を呼ぶだけでよい
・返されたメッセージは呼び出し側で表示する(戻り値をそのまま出力)
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# 親クラスの定義 class Appliance: def __init__(self, name): self.name = name def '''(穴埋め)'''(self): return f"{self.name}を操作しています" # 子クラスの定義(洗濯機) class WashingMachine('''(穴埋め)'''): def '''(穴埋め)'''(self): return f"{self.name}で洗濯を開始します" # 子クラスの定義(冷蔵庫) '''(穴埋め)冷蔵庫クラスを定義し、Applianceを継承してoperateをオーバーライドする ''' # 家電製品のリストを作成し、それぞれの操作を出力します appliances = [WashingMachine("洗濯機"), Refrigerator("冷蔵庫")] # 各家電製品の操作を順に出力 for appliance in appliances: print(appliance.'''(穴埋め)'''()) # 出力:洗濯機で洗濯を開始します, 冷蔵庫で冷蔵を開始します
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例|家電オーバーライドプログラム
例えば以下のようなプログラムが考えられます。
- 正解コード
-
# 親クラスの定義 class Appliance: def __init__(self, name): self.name = name def operate(self): return f"{self.name}を操作しています" # 子クラスの定義(洗濯機) class WashingMachine(Appliance): def operate(self): return f"{self.name}で洗濯を開始します" # 子クラスの定義(冷蔵庫) class Refrigerator(Appliance): def operate(self): return f"{self.name}で冷蔵を開始します" # 家電製品のリストを作成し、それぞれの操作を出力します appliances = [WashingMachine("洗濯機"), Refrigerator("冷蔵庫")] # 各家電製品の操作を順に出力 for appliance in appliances: print(appliance.operate()) # 出力:洗濯機で洗濯を開始します, 冷蔵庫で冷蔵を開始します
解答例の解説|家電オーバーライドプログラムの考え方
正解コードをブロックごとに解説します。
- 詳細解説
-
親クラスの定義
# 親クラスの定義 class Appliance: def __init__(self, name): self.name = name def operate(self): return f"{self.name}を操作しています"
家電の共通部分をひとまとめにするための土台を作っています。
ここでは、各家電が持つ名前という情報をインスタンスに保存し、基本となる操作を表すメソッドを用意します。
基本動作はあくまで“標準のふるまい”として定義しておき、後で子クラス側から上書きできる余地を残します。
動作メッセージは画面に直接表示するのではなく、文字列として返す設計にすることで、呼び出し側が使い方を柔軟に選べます。子クラスの定義
# 子クラスの定義(洗濯機) class WashingMachine(Appliance): def operate(self): return f"{self.name}で洗濯を開始します" # 子クラスの定義(冷蔵庫) class Refrigerator(Appliance): def operate(self): return f"{self.name}で冷蔵を開始します"
共通の土台を受け継いだ上で、家電ごとに振る舞いを変えています。
ここでは、親クラスで用意した基本の操作メソッドと同じ名前・同じ使い方のまま、洗濯機と冷蔵庫に合わせたメッセージを返すように再定義します。
初期化で名前を持たせる仕組みは親から引き継げるので、子クラスでは改めて用意する必要はありません。
これにより、同じメソッド呼び出しでも、どのクラスのインスタンスかによって結果が切り替わる、いわゆる多態性を体験できます。実行結果出力
# 家電製品のリストを作成し、それぞれの操作を出力します appliances = [WashingMachine("洗濯機"), Refrigerator("冷蔵庫")] # 各家電製品の操作を順に出力 for appliance in appliances: print(appliance.operate()) # 出力:洗濯機で洗濯を開始します, 冷蔵庫で冷蔵を開始します
ここでは、異なる種類の家電オブジェクトをひとつの入れ物に並べ、同じ操作名を順に呼び出して結果を表示しています。
どの要素にも同じメソッド名でアクセスできるのは、共通の親クラスを持ち、子クラスでメソッドを上書きしているからです。
これにより、呼び出し方は統一されたまま、中身の型に応じて適切な振る舞いが選ばれる、という多態性の利点を出力で確認できます。
表示は呼び出し側の責務なので、返ってきたメッセージをそのまま画面に出しています。
オーバーライドの疑問解消|FAQと用語のまとめ
初心者がつまずきやすいポイントをFAQとしてまとめ、またよく使う専門用語をわかりやすく整理しました。
理解を深めたいときや、ふと疑問に感じたときに役立ててください。
FAQ|オーバーライドに関するよくある質問
- Q1. オーバーライドと継承の違いは何ですか?
-
継承は親クラスの機能を受け継ぐ仕組みで、オーバーライドはその機能を子クラスで再定義することを指します。
- Q2. オーバーライドする際の注意点は?
-
メソッド名を完全に一致させる必要があります。また、親クラスのメソッドを維持したい場合は
super()
を活用します。
- Q3. オーバーライドはクラス間で自由にできますか?
-
同じ名前のメソッドが親クラスに存在する場合に限り、子クラスでオーバーライドが有効になります。
Python用語集|オーバーライドに関する用語一覧
今回の記事で出てきた用語・関数などを一覧で紹介します。
このサイトに出てくる 全てのPython用語をまとめた用語集 も活用してください。