Pythonの継承

投稿日: 2024年4月2日

Pythonの継承は、あるクラス(サブクラス(派生クラス))が別のクラス(スーパークラス(基底クラス))の属性やメソッドを引き継ぐオブジェクト指向プログラミングの機能です。
継承を使用すると、既存のコードの再利用、拡張が容易になり、コードの重複を減らし、プログラムの保守性を向上させることができます。

このサブクラス(派生クラス)、スーパークラス(基底クラス)って何ですか?

継承はややこしいから例え話を交えて説明するね。

オブジェクト指向プログラミングにおけるクラス間の継承関係には、いくつかの基本的な用語があります。これらの用語は、クラスがどのように他のクラスから属性やメソッドを継承するか、およびクラス同士の階層関係を記述する際に使われます。

スーパークラス(基底クラス)

スーパークラスまたは基底クラスは、他のクラスに属性やメソッドを提供するクラスです。
継承の文脈において、スーパークラスは「親クラス」とも呼ばれ、その機能は一つまたは複数の「子クラス」によって継承されます。基本的に、スーパークラスはより一般的な振る舞いや状態を定義し、それをサブクラスが特化、拡張、またはカスタマイズします。

スーパークラス(基底クラス)を理解するためのたとえ話をしましょう。スーパークラスを「親」、サブクラス(派生クラス)を「子」と考えるとわかりやすいです。

スーパークラス(基底クラス)の例え

想像してみてください。ある家族に、家事全般をこなすことができる「親」がいます。
この「親」は料理、掃除、洗濯という基本的な家事スキルを持っています。この場合、親が持つこれらのスキルは、すべての家事をこなすための「基底」または「基本」スキルです。

この家族にはいくつかの「子」がいて、それぞれが特別なスキルや興味を持っています。
例えば、一人の子は料理が得意で、親から学んだ基本的な料理スキルをもとに、さらに独自のレシピを開発します。もう一人の子は掃除が得意で、親から学んだ掃除スキルに加えて、新しい掃除道具の使い方や効率的な掃除方法を編み出します。

このたとえ話において、「親」はスーパークラス(基底クラス)に相当します。
親が持つ基本的な家事スキルは、家族全員が共通して利用できる「基本機能」です。そして、それぞれの「子」はサブクラス(派生クラス)に相当します。子たちは親から基本スキルを「継承」し、その上で独自の特技や興味に応じて新しいスキルを追加したり、基本スキルを特化させたりします。

このように、スーパークラス(基底クラス)は、一連の基本的な属性やメソッド(この場合は家事スキル)を提供し、サブクラス(派生クラス)はそれらを継承して、特定のニーズに合わせて拡張や特化を行うことができます。
これにより、プログラミングにおいても、コードの再利用性を高め、効率的な開発が可能になります。

サブクラス(派生クラス)

サブクラスまたは派生クラスは、スーパークラスから属性やメソッドを継承するクラスです。
サブクラスはスーパークラスの機能を「拡張」したり、「特化」したりすることができます。つまり、スーパークラスの機能に加えて、新しい属性やメソッドを追加したり、スーパークラスのメソッドをオーバーライド(上書き)して新しい振る舞いを定義したりできます。

サブクラス(派生クラス)を理解するためのたとえ話として、スポーツチームのコーチと選手を考えてみましょう。

サブクラス(派生クラス)の例え

想像してみてください。あるスポーツチームには、全ての基本的なトレーニングメソッドを知っている「総合コーチ」がいます。
この総合コーチは、ランニング、ウェイトトレーニング、基本的な戦術など、あらゆる選手が身につけるべき基本スキルを教えることができます。この総合コーチは、私たちのたとえ話におけるスーパークラス(基底クラス)に相当します。

チームにはさまざまな特殊技能を持つ選手たちがおり、それぞれが総合コーチから学んだ基本スキルを持っています。しかし、特定のポジションや役割に特化した選手は、その基本スキルに加えて独自の特殊技能や戦術を身につけます。たとえば、スプリンター(短距離走者)は、基本的なランニングスキルを基礎としながらも、爆発的なスタートやスピード維持の技術を特化して磨きます。
また、ゴールキーパーは、基本のフィジカルトレーニングに加えて、特別な反射神経のトレーニングやポジショニングのスキルを学びます。

これらの特化した選手たちは、サブクラス(派生クラス)に相当します。彼らは総合コーチ(スーパークラス)から基本スキルを「継承」していますが、自分たちのポジションや役割に合わせて、それらのスキルをさらに発展させ、新しい技能を追加しています。

このたとえ話では、スーパークラス(基底クラス)が提供する「基本スキル」は、すべての選手(サブクラス)に共通の土台となります。それぞれのサブクラス(特化した選手)は、この共通の土台の上に自分たち独自の「特殊技能」を構築し、チーム全体の強みと多様性を高めています。
プログラミングにおいても、サブクラスはスーパークラスの機能を継承しつつ、特定のニーズに合わせて新たな機能や振る舞いを追加することで、より複雑で多様なソフトウェアの開発を可能にします。

継承の例

class Vehicle:  # スーパークラス(基底クラス)
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def display_info(self):
        print(f"This vehicle is a {self.brand} {self.model}.")

class Car(Vehicle):  # サブクラス(派生クラス)
    def __init__(self, brand, model, car_type):
        super().__init__(brand, model)  # スーパークラスのコンストラクタを呼び出す
        self.car_type = car_type

    def display_info(self):
        super().display_info()  # スーパークラスのメソッドを呼び出す
        print(f"It is a {self.car_type}.")

この例では、Vehicleクラスがスーパークラス(基底クラス)で、Carクラスがそのサブクラス(派生クラス)です。CarクラスはVehicleから全ての属性とメソッドを継承し、追加の属性(car_type)と、display_infoメソッドの新しい振る舞いを提供します。

継承を使用することで、既存のコードの再利用、クラス間の関係の明確化、プログラムの保守性と拡張性の向上が可能になります。

記事