Developer

【Python連載】メソッドのオーバーライド
2021.07.27
Lv1

【Python連載】メソッドのオーバーライド

Pythonは、オブジェクト指向と呼ばれるプログラミング言語の一つです。
今回は、メソッドのオーバーライドに関することに紹介します。


オーバーライドとは

クラスの継承では、サブクラスでは、独自の属性とメソッドも定義して使用できます。
スーパークラスで定義されているメソッドもサブクラスでそのまま使用することができますが、そのスーパークラスのメソッドをサブクラス内で同名のメソッドを定義することで上書きしてしまうことが可能です。これを『オーバーライド』といいます。

まずは、次のプログラムの実行結果を見てみましょう。

#スーパークラスの定義
class Person():
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def my_introduction(self):
        print(f"名前は{self.name}、年齢は{self.age}です")

#サブクラスの定義
class Student(Person):
    def __init__(self,name,age,standard_score): 
        self.name = name
        self.age = age
        self.standard_score = standard_score

student1 = Student("Taro", 15, 50) #サブクラスからインスタンスを作成し、スーパークラスのメソッドを実行
student1.my_introduction()
C:\Python> python 13-6-1.py
名前はTaro、年齢は15です

サブクラスのインスタンスを作成し、スーパークラスのmy_introductionメソッドを実行しています。
ではこちらのメソッドを、オーバーライドを利用してstandard_score属性の値も出力できるような形に上書きしてみます。

#スーパークラスの定義
class Person():
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def my_introduction(self):
        print(f"名前は{self.name}、年齢は{self.age}です")

#サブクラスの定義
class Student(Person):
    def __init__(self,name,age,standard_score): 
        self.name = name
        self.age = age
        self.standard_score = standard_score

    def my_introduction(self):  #メソッドのオーバーライド
        print(f"名前は{self.name}、年齢は{self.age}、偏差値は{self.standard_score}です")

student1 = Student("Taro", 15, 50) #サブクラスからインスタンスを作成し、メソッドを実行
student1.my_introduction()
C:\Python> python 13-6-2.py
名前はTaro、年齢は15、偏差値は50です

サブクラス側で定義されたmy_introductionメソッドの内容が実行されていることがわかります。

これがオーバーライドとなります。
ですが、『別にオーバーライドを使用しないで、サブクラス内で一から別メソッドを作成したら駄目なの?』と思いませんでしたか?
別に問題はないのですが・・・
今回の例ではサブクラスが一つしかありませんが、コードがもっと複雑な形になってくると、既存のものを再利用・拡張することの恩恵は大きくなってきます。
スーパークラスにあるものをベースとした方が、可読性が上がります。
ですので、今回の継承やオーバーライドを理解しておくことは後々重要になってきますので、覚えておきましょう。


まとめ

スーパークラスのメソッドをサブクラス内で同名のメソッドで新たに定義することを『オーバーライド』といいます。


確認問題

次のようなプログラムがあります。

class Person():
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def my_introduction(self):
        print(f"名前は{self.name}、年齢は{self.age}です")

class Student(Person):
    def __init__(self,name,age,standard_score): 
        self.name = name
        self.age = age
        self.standard_score = standard_score

    def my_introduction(self):
        print(f"名前は{self.name}、年齢は{self.age}、偏差値は{self.standard_score}です")

person1 = Person("Jiro", "23")
student1 = Student("Taro", 15, 50)
person1.my_introduction()
student1.my_introduction()

21行目、22行目では同名のメソッドが実行されています。
どのような出力結果になるか、考えてみましょう。

答えは次回の記事の最後に!
【Python連載】ゲッター・セッターの利用

前回の確認問題の回答例

前回の記事はこちら→【Python連載】クラスの継承

次のようなプログラムがあります。

class Person():
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def my_introduction(self):
        print(f"名前は{self.name}、年齢は{self.age}です")

class Student():
    def __init__(self,name,age,standard_score = 50):
        self.name = name
        self.age = age
        self.standard_score = standard_score

Student1 = Student("Taro",15)
Student1.my_introduction()

このプログラムを実行すると、以下のようなエラーが発生します。

line 17, in <module>
Student1.my_introduction()

AttributeError: ‘Student’ object has no attribute ‘my_introduction’

このエラーの原因を考えてみましょう。

・以下が解答になります。
9行目のStudentクラスの定義の部分で、Personクラスを継承する形になっていません。
そのため、StudentクラスのインスタンスでPersonクラスのメソッドを実行することは出来ません。

class サブクラス名(スーパークラス名):
のように記載することで継承となります。