🚀 ニフティ’s Notion

【オブジェクト指向2024 #6】継承とポリモーフィズム

継承とは (きもち)

☝️
継承 (きもち的な側面)

クラス同士の 概念上・意味上の共通部分 を別のクラスとして 抽出 し、コードを共通化するためのしくみ。

割引にせよ、固定値値引きにせよ、どちらもキャンペーンであることに変わりはない。具体的には、たとえば、どちらも「定価からキャンペーンを適用した金額を計算できる」。継承のしくみを使うと、この共通部分を Campaign というクラスとして抽出し、 RateDiscountCampaign ValueDiscountCampaign がいずれも Campaign の一種であることを表明できる。

継承とは (プログラム的な話)

☝️
継承 (プログラム的な側面)

あるクラス (親クラス) のメンバーやメソッドを引き継いだ別のクラス (子クラス) を作成すること。

Python では次のように書く。

class 親クラス名:
    def メソッドA(self):
        print("Aが呼ばれたよ")

    def メソッドB(self):
        print("Bが呼ばれたからAを呼ぶよ")
        self.メソッドA()


class 子クラス名(親クラス名):
    pass

オーバーライド

継承には、メソッドのオーバーライドという仕組みがある。

☝️
メソッドのオーバーライド

親クラスで定義されたメソッドを、子クラスで上書きして定義すること。

これを行うためには、子クラスで同じ名前の関数を定義すれば良い。 ( @override をつけるとより丁寧)

from typing import override

class 子クラス名(親クラス名):
    # オーバーライドして上書きする。
    # @override をつけると (うっかり同じ名前なってしまったんじゃなくて)
    # 意図的にやっていることを表現できる。
    @override
    def メソッドA(self):
        print("オーバーライドされたAだよ")
        
c = 子クラス名()
c.メソッドA()
# オーバーライドされたAだよ

ポリモーフィズム

親クラスに定義されているメソッドBがメソッドAを呼び出しているとする。

子クラスでメソッドAをオーバーライドしたとしよう。そのうえでメソッドBを実行すると、その中でメソッドAは親クラスで定義されていたもともとの振る舞いではなくオーバーライドされたメソッドAの振る舞いをする。これにより、メソッドBを一切書き換えることなしに、メソッドBが起こす結果を間接的に変化させることができる。

☝️
ポリモーフィズム

異なるクラスのインスタンスが同じ名前のメソッドを定義しているとき、そのメソッドが別のコードから呼び出された際に実際のインスタンスに応じた異なる挙動をすること。

例えば、以下のコードは 派生クラス1 派生クラス2 で異なる振る舞いをする。

class 基底クラス名:
    def メソッドA(self):
        print("Aが呼ばれたよ")

    def メソッドB(self):
        print("Bが呼ばれたからAを呼ぶよ")
        self.メソッドA()


class 派生クラス名1(基底クラス名):
    @override
    def メソッドA(self):
        print("1でオーバーライドされたAだよ")


class 派生クラス名2(基底クラス名):
    @override
    def メソッドA(self):
        print("別の2でオーバーライドされたAだよ")


c1 = 派生クラス名1()
c1.メソッドB()
# Bが呼ばれたからAを呼ぶよ
# 1でオーバーライドされたAだよ

c2 = 派生クラス名2()
c2.メソッドB()
# Bが呼ばれたからAを呼ぶよ
# 別の2でオーバーライドされたAだよ

次: 📄 【オブジェクト指向2024 #7】継承でキャンペーンを整理する