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

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:メソッドのオーバーライド

この記事の練習問題で使用する知識:
レッスン1~4の知識クラスの定義と使用__init__メソッドメソッドの定義と使用カプセル化プロパティクラスの継承メソッドのオーバーライド静的メソッド

<<前の問題 問題集Top 次の問題>>

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

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

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

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

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

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

まとめ

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

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

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

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

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

この問題の要件

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

  • 親クラス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__メソッドはクラスのインスタンスを作成する際に自動的に呼び出される初期化メソッドです。

たとえば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で出力します。

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

まとめ

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

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

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

<<前の問題 問題集Top 次の問題>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Python記事トップへ戻る
    トップページへ戻る