【レッスン5-06】オーバーライドで動作を自在に変更しよう|Python学習

ながみえ
【Python学習記事のアイキャッチ画像】Lesson5-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学習記事のアイキャッチ画像】Lesson5-5 クラスの継承を理解しよう

Pythonの記事一覧

Python学習カテゴリの親ページ用アイキャッチ画像(テキスト&問題集)、記事一覧へのリンク案内

次のページ>>

【Python学習記事のアイキャッチ画像】Lesson5-7 静的メソッドを理解しよう

オーバーライドとは? 継承関係におけるメソッドの再定義

ここからメソッドのオーバーライドの説明に入ります。

ページ下部にはこのページで出てくる用語の意味をまとめた 用語集 もありますので、分からない言葉が出てきたらそちらも参考にしてください。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

メソッドのオーバーライドとは、親クラスで定義されたメソッドを子クラスで再定義する機能です。

オブジェクト指向プログラミングの重要な概念であり、親クラスのメソッドの基本的な動作を変更したい場合に使用されます。これにより、さらに柔軟なクラス設計が可能となります。

たとえば動物クラスに「鳴く」メソッドが定義されている場合、その動作を異なる動物ごとにカスタマイズすることができます。

【初心者向け】Pythonのオブジェクト指向を分かりやすくまとめた概念図。 特にクラスの継承、オーバーライド、抽象クラス、ミックスインクラス、データクラス、静的メソッドの関係性を視覚的に理解できるようまとめている。

メソッドのオーバーライドの使用例

ここでは動物のクラスを例にして、メソッドのオーバーライドを見ていきます。

親クラスで「鳴く」メソッドが定義されており、これを子クラスで上書き(オーバーライド)しています。

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という親クラスにmake_soundというメソッドがあり、DogCatという子クラスでそれぞれ異なる実装を行っています。

Dogクラスでは「ワンワン!」、Catクラスでは「ニャーニャー」と鳴く動作にオーバーライドされています。

このコードを実行すると、以下のように出力されます。

動物が鳴いています
ワンワン!
ニャーニャー

メソッドのオーバーライドの利点

メソッドのオーバーライドを使うことでコードの再利用性が向上し、柔軟に動作を変更することができます。

親クラスに共通のメソッドを定義し、子クラスで必要な場合にその動作をカスタマイズすることで、無駄なコードの繰り返しを防ぎ、保守性の高いコードを書くことが可能です。

またオーバーライドによって、子クラスに特有の振る舞いを簡単に実装できるため、クラス設計がより直感的になります。

まとめ

メソッドのオーバーライドは親クラスの機能を子クラスでカスタマイズするための強力な手段です。

この機能を使うことでコードの再利用性が高まり、オブジェクト指向プログラミングの利点を活かすことができます。

練習問題:家電製品の動作をシミュレーションしよう

【Python】勉強猫がノートパソコンに向かい、練習問題に挑戦する様子。記事内の休憩用イラスト

クラスの継承とメソッドのオーバーライドを使った家電製品のシミュレーションプログラムを作成しましょう。

親クラスで基本的な家電の操作を定義し、洗濯機と冷蔵庫の子クラスでそれぞれの動作をカスタマイズします。

問題の詳細条件

以下の要件に従ってコードを完成させてください。

  • 親クラスApplianceを定義し、名前を設定する__init__メソッドを作成すること。
  • 親クラスで家電製品を操作するoperateメソッドを定義すること。
  • WashingMachineクラスとRefrigeratorクラスを親クラスから継承し、それぞれのoperateメソッドをオーバーライドすること。
  • 各家電の操作を順に出力すること。

ただし、以下のような実行結果となるコードを書くこと。

洗濯機で洗濯を開始します
冷蔵庫で冷蔵を開始します

【ヒント】難しいと感じる人だけ見よう

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:親クラスApplianceの定義
  □ __init__メソッドの定義
  □ □ 引数nameをインスタンス変数self.nameに代入
  □ operateメソッドの定義
  □ □ 家電製品の操作メッセージを返す

2:子クラスWashingMachineの定義
  □ operateメソッドをオーバーライドして定義
  □ □ 洗濯機の操作メッセージを返す

3:子クラスRefrigeratorの定義
  □ operateメソッドをオーバーライドして定義
  □ □ 冷蔵庫の操作メッセージを返す

4:家電製品のリストappliancesを作成
  □ WashingMachineとRefrigeratorのインスタンスを生成し、リストに追加

5:for文によるループ処理
  □ 各家電製品のoperateメソッドを実行して出力

Q
ヒント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】ここに家電製品の操作メッセージを出力するコードを書いてください。"""

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

問題の答え合わせと解説

この問題の一つの正解例とそのコードの解説を以下に示します。

一つの正解例

例えば以下のようなプログラムが考えられます。

Q
正解コード
# 親クラスの定義
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())  # 出力:洗濯機で洗濯を開始します, 冷蔵庫で冷蔵を開始します

正解例の詳細解説

正解コードをブロックごとに解説します。

Q
詳細解説

親クラスの定義と__init__メソッド

def __init__(self, name):
    self.name = name

まず親クラスApplianceが定義されています。このクラスには__init__メソッドがあり、家電製品の名前を設定します。

__init__メソッドはクラスのインスタンスを作成する際に自動的に呼び出される初期化メソッドです。

たとえばWashingMachineRefrigeratorを作成するときに、家電製品の名前を設定する役割を果たします。

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}で冷蔵を開始します"

このプログラムのポイントは「メソッドのオーバーライド」です。

メソッドのオーバーライドとは、親クラスで定義されたメソッドを子クラスで上書きすることを意味します。

ここではWashingMachineRefrigeratorという2つの子クラスが親クラスApplianceoperateメソッドをオーバーライドしています。

  • WashingMachineクラスでは、洗濯機の動作メッセージを返すようにオーバーライドしています。
  • Refrigeratorクラスでは、冷蔵庫の動作メッセージを返すようにオーバーライドしています。

これにより親クラスの基本動作を子クラスでカスタマイズすることが可能になります。

たとえば、operateメソッドは同じ名前ですが、洗濯機では「洗濯を開始」、冷蔵庫では「冷蔵を開始」という異なるメッセージを出力します。

家電リストの作成と動作の出力

for appliance in appliances:
    print(appliance.operate())

最後に家電製品のインスタンスをリストappliancesに追加し、forループを使って各家電製品の操作を順に実行します。

このループはリスト内の各家電製品に対してoperateメソッドを呼び出し、その結果をprintで出力します。

各家電製品がオーバーライドしたメソッドを持つため、対応する操作メッセージが表示されます。

まとめ

このコードではクラスの継承とメソッドのオーバーライドの仕組みを理解できます。

メソッドのオーバーライドを使うことで、親クラスで定義された機能を子クラスで簡単にカスタマイズできることがわかりました。

これによりコードの再利用性が高まり、拡張性も向上します。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいPython学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

【Python学習記事のアイキャッチ画像】Lesson5-5 クラスの継承を理解しよう

Pythonの記事一覧

Python学習カテゴリの親ページ用アイキャッチ画像(テキスト&問題集)、記事一覧へのリンク案内

次のページ>>

【Python学習記事のアイキャッチ画像】Lesson5-7 静的メソッドを理解しよう

Python用語集|メソッドのオーバーライド編

今回の記事で出てきた用語・関数などを一覧で紹介します。

このサイトに出てくる 全てのPython用語をまとめた用語集 も活用してください。

Python用語定義・使い方の概要解説記事へのリンク
クラスデータとその操作(メソッド)をまとめた設計図。オブジェクト生成のテンプレートとなる構造Lesson5-1
継承既存のクラス(親クラス)の機能を新しいクラス(子クラス)に引き継ぐ仕組み。コードの再利用に有効Lesson5-5
オーバーライド子クラスが親クラスから継承したメソッドを同名で再定義し、振る舞いを変更すること本記事

FAQ|Pythonのオーバーライドの基本

Q
Q1. オーバーライドと継承の違いは何ですか?

継承は親クラスの機能を受け継ぐ仕組みで、オーバーライドはその機能を子クラスで再定義することを指します。

Q
Q2. オーバーライドする際の注意点は?

メソッド名を完全に一致させる必要があります。また、親クラスのメソッドを維持したい場合はsuper()を活用します。

Q
Q3. オーバーライドはクラス間で自由にできますか?

同じ名前のメソッドが親クラスに存在する場合に限り、子クラスでオーバーライドが有効になります。

記事URLをコピーしました