【Python入門】クラスの継承!(オーバーライド ・super)

Python Python

Pythonでクラスを使う際に継承する方法について書いています。

今回は下記の内容について、記載しています。

・クラス継承について
・クラスをオーバーライドする方法について
・superメソッドについて

クラスの継承とは?

クラスを継承すると、継承元(親クラス)が持っているインスタンス変数やメソッドなどを継承先(子クラス)で使えるようになります。
クラスを継承する際には、classキーワードでクラスを作成した時に、丸括弧の中に継承したいクラスを指定します。
Pythonでクラス継承イメージ

次項から、実際に継承するサンプルコードを確認していきましょう。

Pythonでクラスを継承するには?

Pythonでクラスを継承するサンプルコードを見ていきます。

クラスを作成して継承する

RPGのキャラクターを題材に、下記のクラスを作ってみました。

class Character():
    def __init__(self, name, hp, mp):
        self.name = name
        self.hp = hp
        self.mp = mp

    def showCharacterInfo(self):
        print(f"キャラクター名: {self.name}")
        print(f"HP: {self.hp}")
        print(f"MP: {self.mp}")

Characterクラスを作成しました。
コンストラクタで名前(name)とHPとMPを設定します。
showCharacterInfoメソッドでは、Characterインスタンスに設定した内容をprint関数で出力するようにしました。

このCharacterクラスを継承する勇者(Hero)クラスを作成してみます。

class Hero(Character):
    pass

Heroクラスを作成しました。
丸括弧(())の中にCharacterクラスを指定しています。これで継承ができました。
Heroクラスには何も実装がないですが、継承したのでCharacterクラスで実装されているインスタンス変数やメソッドを使用できます。

作成したクラスを使ってみる

実際に2つのクラスを使ってみます。
どちらも同じようにインスタンス化することができます。

people_a = Character("太郎", "100", "20")
people_a.showCharacterInfo()

hero = Hero("勇者", "300", "150")
hero.showCharacterInfo()

people_a変数にCharacterクラスを使ってインスタンスを作成しました。
showCharacterInfoメソッドを呼んでいます。
出力内容は下記のようになり、設定値がちゃんと出力されました。

キャラクター名: 太郎
HP: 100
MP: 20

同様にして、Heroクラスのインスタンスを作成しています。
Heroクラスには実装がないですが、継承しているため、同じメソッドとインスタンス変数が使えます。
showCharacterInfoメソッドを呼んで、出力内容を確認しました。

キャラクター名: 勇者
HP: 300
MP: 150

このように継承することで、同じインスタンス変数とメソッドが使えることが確認できました。

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

オーバーライドは、親クラスで定義されているメソッドを、子クラスで上書きすることです。
親クラスのメソッドを子クラスで上書きすることで、動作を変えることができます。

Characterクラスへhelloメソッドの実装する

Characterクラスの実装として、helloメソッドを追加しました。
このメソッドは、挨拶文を出力するメソッドです。

class Character():
    def __init__(self, name, hp, mp):
        self.name = name
        self.hp = hp
        self.mp = mp

    def showCharacterInfo(self):
        print(f"キャラクター名: {self.name}")
        print(f"HP: {self.hp}")
        print(f"MP: {self.mp}")

    def hello(self):
        print(f"私は{self.name}です。キャラクターです。")

Characterクラスのhelloメソッドを実行する

このように実行します。

people_a = Character("太郎", "100", "20")
people_a.hello()

そうすると、挨拶文が表示されました。

私は太郎です。キャラクターです。

Heroクラスでhelloメソッドをオーバーライドする

CharacterクラスのhelloメソッドをHeroクラスでオーバーライドします。
下記のように実装を書きました。

class Hero(Character):
    def hello(self):
        print("私は勇者です。世界を救います!")

同じ名前のメソッドを作成することで、オーバーライドされます。
helloメソッドを呼び出すと、子クラスのhelloメソッドが動作するようになります。

Heroクラスのhelloメソッドを実行する

作成したhelloメソッドを、下記のように呼び出してみます。

hero = Hero("勇者", "300", "150")
hero.hello()

そうすると、このように子クラスに実装したhelloメソッドが動きました。
親クラスのhelloメソッドは動作してないですね。オーバーライドされたことが確認できました。

私は勇者です。世界を救います!

親(super)メソッドの呼び出し

親クラスのメソッドを子クラスから明示的に呼び出すこともできます。

Heroクラスに職業を実装する

Heroクラスに職業(job)を実装します。

class Hero(Character):
    def __init__(self, name, hp, mp, job):
        super().__init__(name, hp, mp)
        self.job = job

    def showCharacterInfo(self):
        super().showCharacterInfo()
        print(f"職業: {self.job}")

    def hello(self):
        print("私は勇者です。世界を救います!")

コンストラクタの__init__メソッドをオーバーライドしています。
引数の最後に職業(job)を追加しました。

処理の中でsuper()を使って、親の__init__メソッドを呼び出しています。
こうすることで、親クラスのメソッドが呼び出されて処理されます。(各インスタンス変数の設定)
その後に、Heroクラスで独自に作成したjob変数に、引数から受け取った職業の文字列を設定しています。

同じようにして、職業を表示させるために、showCharacterInfoメソッドを修正しました。
super().showCharacterInfo()で親クラスのshowCharacterInfoメソッドが動きます。
その次の行で、職業を表示するようにしました。

修正したHeroクラスを実行する

修正したHeroクラスを使って、下記のようにインスタンスを作って実行してみました。
名前が勇者で、職業が剣士です😅

hero = Hero("勇者", "300", "150", "剣士")
hero.showCharacterInfo()

実行すると、このように職業の文字列がインスタンス変数に設定され、表示されるようになりました。

キャラクター名: 勇者
HP: 300
MP: 150
職業: 剣士

このようにsuper()を使うことで親クラスを利用しながら、子クラスで独自の実装を追加できました。

おわりに

今回はPythonでクラスの継承をする方法について書きました。
クラスを継承して、効率よく処理を追加していきましょう。

コメント

タイトルとURLをコピーしました