検索

キーワード


目次

Pythonにおけるクラス継承について【初心者向け解説記事】

  • 公開日:2023-07-02 18:38:35
  • 最終更新日:2023-07-02 18:36:49
Pythonにおけるクラス継承について【初心者向け解説記事】

Workteria(ワークテリア)では難易度の高いものから低いものまで、スキルや経験に合わせた案件を多数揃えています。会員登録は無料ですので、ぜひ会員登録してご希望の案件を探してみてください!

フリーランス/正社員のエンジニアとして活躍するには、ご自身のスキルや経験に合わせた仕事を選ぶことが大切です。ご希望の案件がみつからない場合はお気軽にお問い合わせください!ユーザ満足度の高いキャリアコンサルタントが在籍していますので、希望条件や悩み事などなんでもご相談ください。ご希望にピッタリの案件をご紹介させていただきます。

Pythonにおけるクラス継承とは?

Pythonにおけるクラスの継承とは、あるクラス(親クラス、または基底クラスと呼ばれます)が持つ属性やメソッドを、新たに作成されるクラス(子クラス、または派生クラスと呼ばれます)が引き継ぐことを指します。これにより、親クラスで定義した機能を子クラスでも利用できるようになります。


Pythonでの継承の基本

Pythonでの継承は、親クラスを定義した後、子クラスを作成することで行います。子クラスの作成は、クラス定義時の括弧内に親クラスの名前を指定することで行います。例えば、親クラス(基底クラス)として社員を表す以下のEmployeeクラスが存在するとします。

class Employee:
    # コンストラクタ
    def __init__(self, id, name, position, salary):
        self.id = id                # 社員ID
        self.name = name            # 社員氏名
        self.position = position    # 役職
        self.salary = salary        # 給与

    # 給与を増減するクラスメソッド
    def give_raise(self, amount):
        self.salary += amount

Employeeクラスの子クラス(派生クラス)として管理職を表すManagerクラスを作りたい場合、次のように定義します。

#管理職に部下のリストを持たせる
class Manager(Employee):
    def __init__(self, id, name, salary, subordinates):
        super().__init__(id, name, "マネージャー", salary)   # 親クラスのコンストラクタを呼び出す
        self.subordinates = subordinates                  # 管理職に部下のリストを表す属性を追加

ここで、super()関数を使うと親クラスのメソッドを呼び出すことができます。これにより、親クラスで定義した__init__メソッドを再利用し、役職を"マネージャー"と固定しています。

実際にこれらのクラスを使うと以下のようになります。子クラスは親クラスの属性とメソッドを引き継ぐため、親クラスで定義したgive_raiseメソッドを子クラスでも使用できます。

manager = Manager(1, "田中", 500000, ["佐藤", "鈴木"])
manager.give_raise(20000)
print(manager.salary)       # 520000
print(manager.subordinates) # ['佐藤', '鈴木']


メソッドの上書き(オーバーライド)

また、子クラスでは親クラスで定義したメソッドを上書き(オーバーライド)することも可能です。例えば、Managerクラスではgive_raiseメソッドを上書きし、昇給額にマネージャーとしてのボーナスを追加することができます。

class Manager(Employee):
    # ...
    def give_raise(self, amount):
        self.salary += amount + 10000


複数の親クラスからの継承(多重継承)

Pythonでは、1つの子クラスが複数の親クラスから継承することが可能です。これを多重継承と言います。多重継承は、異なるクラスが提供する機能を1つのクラスに統合する際に非常に便利です。

以下に、Employeeクラスと別のクラスとして定義した、勤務時間を表すWorkHoursクラスから、両方を継承したManagerクラスの例を示します。

class Employee:
    def __init__(self, id, name, position, salary):
        self.id = id
        self.name = name
        self.position = position
        self.salary = salary

    def give_raise(self, amount):
        self.salary += amount

class WorkHours:
    def __init__(self, work_hours):
        self.work_hours = work_hours

    def add_hours(self, hours):
        self.work_hours += hours

class Manager(Employee, WorkHours):
    def __init__(self, id, name, salary, work_hours, subordinates):
        Employee.__init__(self, id, name, "Manager", salary)
        WorkHours.__init__(self, work_hours)
        self.subordinates = subordinates

ここで、ManagerクラスはEmployeeクラスとWorkHoursクラスの両方から継承しています。これにより、Managerクラスはgive_raiseメソッドとadd_hoursメソッドの両方を利用することができます。

しかし、多重継承には注意が必要です。もし2つの親クラスが同じ名前のメソッドを持っていた場合、子クラスはどちらのメソッドを使用するのか混乱する可能性があります。Pythonはこの問題を解決するために、メソッド解決順序(Method Resolution Order, MRO)というルールを使用します。MROは、Pythonが属性やメソッドを検索する順序を定義します。このルールにより、多重継承が引き起こす可能性のある名前の衝突や曖昧さを解決します。しかし、多重継承は複雑性を増すため、必要な場合にのみ慎重に使用することをおすすめします。


メソッド解決順序(Method Resolution Order, MRO)

Pythonの多重継承では、複数の親クラスに同名のメソッドが存在する場合に、どのクラスのメソッドを優先的に呼び出すべきかを決めるためのルールが必要となります。このルールをメソッド解決順序(MRO)といいます。

PythonのMROは、子クラス自体から始めて、最初の親クラス、次の親クラスとたどっていくことで、メソッドを探します。最初に見つけたメソッドが呼び出されます。これは、"左から右、深さ優先"の原則に基づいています。

例えば、以下のようにEmployeeクラスとWorkHoursクラスが同名のメソッドshow_infoを持っていて、Managerクラスがこれらを多重継承しているとします。

class Employee:
    def __init__(self, id, name, position, salary):
        self.id = id
        self.name = name
        self.position = position
        self.salary = salary

    # 社員の役職を表示
    def show_info(self):
        return f"{self.name} ({self.position})"

class WorkHours:
    def __init__(self, work_hours):
        self.work_hours = work_hours

    # 社員の勤務時間を表示
    def show_info(self):
        return f"Work hours: {self.work_hours}"

class Manager(Employee, WorkHours):
    def __init__(self, id, name, salary, work_hours, subordinates):
        Employee.__init__(self, id, name, "Manager", salary)
        WorkHours.__init__(self, work_hours)
        self.subordinates = subordinates

manager = Manager(1, "田中", 500000, 150,  ["佐藤", "鈴木"])
print(manager.show_info())  # 田中 (Manager)


この場合、Managerクラスのインスタンスがshow_infoメソッドを呼び出すと、Employeeクラスのshow_infoが優先的に呼び出されます。

Pythonでは、mroメソッドを使ってクラスのMROを確認することができます。Manager.mro()のように使用します。これにより、Pythonがメソッドをどの順序で探しに行くかを把握することができます。

print(Manager.mro())  # [<class '__main__.Manager'>, <class '__main__.Employee'>, <class '__main__.WorkHours'>, <class 'object'>]

MROはPythonの多重継承の挙動を理解するための重要な概念です。多重継承を利用する際には、このMROを意識することが重要です。


まとめ

Pythonのクラス継承は、コードの再利用性と保守性を向上させる強力なツールです。継承を使用することで、既存のクラスの属性とメソッドを新しいクラスで再利用できます。また、子クラスでは親クラスのメソッドを上書き(オーバーライド)して、新たな振る舞いを実装することが可能です。

一方、Pythonでは複数の親クラスから継承することも可能ですが、この多重継承はコードの複雑性を増加させるため、注意して使用する必要があります。多重継承が適切に使用されると、多くの異なるクラスの特性を1つのクラスに組み合わせることができますが、同じ名前のメソッドが複数の親クラスで定義されている場合など、混乱を招く可能性もあります。

Pythonのクラス継承の機能を理解し、適切に使用することで、コードを再利用可能にすることが出来、保守しやすくなります。ただし、その際には常にコードの可読性と保守性を念頭に置いて設計を行いましょう。


【著者】

ゆうさい

フォワードソフト株式会社のエンジニア。Java、Python、JavaScript、C#などの言語の他、クラウドやネットワーク技術を勉強しています。PythonやVBAを使った自動化で楽をする方法を考えるのが好きです。 最近はジェネレーティブAIの業務利用に関する検証を行っています。 資格を通じて知識を吸収することを心がけており、セキュリティスペシャリスト、データベーススペシャリスト、応用情報技術者、Oracle Certified Java Programmer Gold SE 11、Pythin3 エンジニア認定試験、HTML5プロフェッショナル認定試験レベル2、AWSプラクティショナーなどの情報資格を保有しています。

編集した記事一覧

正社員/フリーランスの方でこのようなお悩みありませんか?

  • 自分に合う案件を定期的に紹介してもらいたい
  • 週2、リモートワークなど自由な働き方をしてみたい
  • 面倒な案件探し・契約周りは任せて仕事に集中したい

そのような方はぜひ、Workteriaサイトをご利用ください!

  • 定期的にご本人に合う高額案件を紹介

  • リモートワークなど自由な働き方ができる案件多数

  • 専属エージェントが契約や請求をトータルサポート