Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

クラスが親クラスから継承するとき、子クラスは独自のインスタンス変数やメソッドを持つことができますが、時には親のコードの一部を使う必要があります。

ここで登場するのがsuper()関数です。
super()は親クラスの名前をハードコードしなくても、子クラスが親クラスのメソッド(間接的に属性も)にアクセスできるようにします。

super()の最も一般的な使い方のひとつは、子クラス内で親のコンストラクタ__init__)を呼び出すことで、親が自分の属性を設定した後に子クラスが新しい属性を追加できるようにすることです。

子クラスが独自の__init__メソッドを定義すると、親の__init__は上書きされます。つまり、子クラスのオブジェクトを作成したときは子の__init__だけが実行され、親のコンストラクタは自動的に呼び出されません。その結果、親の__init__で設定された初期化処理やデフォルト値、属性はすべてスキップされてしまい、子オブジェクトにおいて未定義のままとなります。これは、親クラスが重要な初期化処理を担っていた場合、予期しないエラーの原因になります。その動作を失わないために、子クラスのコンストラクタ内でsuper().__init__()を明示的に呼び出し、親の初期化処理を先に実行してから子クラスの追加や上書きを行うべきです。

さっそく見てみましょう!


なぜsuper().__init__()を使うのか?

サブクラスを作るとき、追加のデータを持たせるかもしれません。
しかし、親の属性は適切に初期化したいです。親の初期化コードを書き直す代わりに、super().__init__()を使って呼び出すだけで済みます。

例:サブクラスに新しい属性を追加する

Animalクラスがnameageを保存するとします。
これを継承したDogサブクラスを作り、犬のbreed(種類)も保存したいですが、nameageの設定はAnimalのコンストラクタを使いたいです。

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

class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, age)  # Animalのコンストラクタを呼ぶ
        self.breed = breed           # Dog独自の属性を追加

仕組みをステップで説明

  1. Dogオブジェクトを作ると、PythonはDogクラスの__init__を実行します。
  2. Dog.__init__のなかでsuper().__init__(name, age)Animal.__init__を呼び出します。
  3. 親のコンストラクタ(Animal.__init__)がself.nameself.ageを設定します。
  4. 制御がDog.__init__に戻り、self.breedを設定します。

こうすることで:

  • 親の属性は親が意図した通りに正しく初期化されます。
  • 子クラスはコードを重複させずに独自の属性を追加可能です。

クラスの使い方

dog = Dog("Rex", 4, "Golden Retriever")

print(dog.name)   # Rex
print(dog.age)    # 4
print(dog.breed)  # Golden Retriever

なぜ親クラス名を直接呼ぶよりsuper()が良いのか

直接Animal.__init__(self, name, age)と呼べますが、super()の方が柔軟です:

  • 多重継承にも自動で対応します(複数の親から継承している場合)。
  • 親クラス名が変わっても、コードのすべての呼び出しを変更する必要がありません。
  • 明示的に親クラスのメソッドを呼んでいることが伝わりやすいです。
ヒント:子クラスの属性を設定する前に必ず`super().__init__()`を呼び、親のすべての属性を使える状態にしましょう。

まとめ

super()は親クラスへの接続リンクです。 以下の場合に使ってください:

  • 親の初期設定コードを再利用したいとき。
  • 親の機能を重複せずに拡張したいとき。
  • クリーンで保守しやすく、クラス階層の変更に強いコードにしたいとき。

次のレッスンではプライベートメソッドと変数について学びます。これはクラスの内部データを外部からアクセスや変更されないように守る方法です。