Python - 継承
Pythonでの継承とは?
継承は、オブジェクト指向プログラミング(OOP)の基本概念の一つで、あるクラスが別のクラスのプロパティとメソッドを継承することができます。これにより、同じコードを再度書くことなく、既存のクラスに基づいて新しいクラスを作成することができ、コードの再利用性とモジュラー性が向上します。Pythonでは、継承は class
キーワードの後に親クラスの名前を括弧内に入れて実装されます。
親クラスの作成
まず、簡単な親クラス Animal
を作成しましょう:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("サブクラスはこのメソッドを実装する必要があります")
この例では、Animal
クラスを定義し、__init__
メソッドで name
属性を初期化し、speak
メソッドで NotImplementedError
を発生させています。このエラーは、サブクラスが speak
メソッドの独自の実装を提供しない場合に発生します。
子クラスの作成
次に、Animal
クラスを継承した子クラス Dog
を作成しましょう:
class Dog(Animal):
def speak(self):
return f"{self.name} は ワウ!と吠えます"
Dog
クラスは、Animal
クラスのすべての属性とメソッドを継承しますが、独自の実装を提供する speak
メソッドを持ちます。Dog
クラスのインスタンスを作成し、その speak
メソッドを呼び出すと、エラーを発生させるのではなく、"[犬の名前] は ワウ!と吠えます" と表示されます。
my_dog = Dog("ブディ")
print(my_dog.speak()) # 出力: ブディ は ワウ!と吠えます
継承の種類
Pythonには3種類の継承があります:単一継承、複数継承、多段継承、以及び階層的継承です。それぞれのタイプを詳しく説明します。
Python - 単一継承
単一継承は最も一般的な継承形式で、クラスが1つの親クラスから継承する場合です。上記の Dog
クラスが Animal
クラスを継承するのは、単一継承の例です。
Python - 複数継承
複数継承は、クラスが複数の親クラスから継承する場合です。しかし、Pythonはクラス定義の構文で直接複数継承をサポートしていません。代わりに、"ミックスイン"または"インターフェース"技術を使用して複数継承を実現します。
メソッド解決順序(MRO)
Pythonは、C3線形化アルゴリズムを使用して、メソッドを探す際に親クラスを検索する順序を決定します。MROは、各クラスがメソッド解決順序に最大1回だけ現れ、クラス定義における親クラスの順序を保持することを保証します。
Python - 多段継承
多段継承は、クラスがサブクラスから継承することで、クラスの階層構造を形成する場合です。以下はその例です:
class Mammal(Animal):
pass
class Cat(Mammal):
def speak(self):
return f"{self.name} は ニャー!と鳴きます"
この場合、Cat
クラスは Mammal
クラスを継承し、Mammal
クラスは Animal
クラスを継承します。これにより、多段継承の階層構造が形成されます。
Python - 階層的継承
階層的継承は、複数のサブクラスが1つのスーパークラスを継承することを含みます。例えば:
class Reptile(Animal):
pass
class Snake(Reptile):
def speak(self):
return f"{self.name} は ヒス!と鳴きます"
class Lizard(Reptile):
def speak(self):
return f"{self.name} は クロールします"
この場合、Snake
と Lizard
クラスはどちらも Reptile
クラスを継承し、Reptile
クラスは Animal
クラスを継承します。これにより、階層的な継承構造が形成されます。
Python - 混合継承
混合継承は、複数継承と他の継承の特徴を組み合わせたものです。Pythonでは直接サポートされていませんが、ミックスインを使用するか、異なるタイプの継承を組み合わせることで実現できます。
super() 関数
super()
関数は、サブクラス内で親クラスのメソッドを呼び出すために使用されます。親クラスのメソッドを拡張またはオーバーライドしながら、その機能の一部を保持したい場合に特に役立ちます。以下はその例です:
class Bird(Animal):
def __init__(self, name, wingspan):
super().__init__(name)
self.wingspan = wingspan
def speak(self):
return f"{self.name} は チューブ!と鳴きます"
この場合、Bird
クラスは Animal
クラスを継承し、super()
関数を使用して親クラスの __init__
メソッドを呼び出します。これにより、name
属性が適切に初期化されます。また、Bird
クラスは独自の実装を提供する speak
メソッドを持ちます。
my_bird = Bird("チューティ", 10)
print(my_bird.speak()) # 出力: チューティ は チューブ!と鳴きます
継承を使用することで、より特殊化されたクラスを作成し、親クラスの機能を継承して拡張することができ、コードの再利用性と整理性が向上します。継承はOOPの一環に過ぎず、ポリモーフィズム、封印、抽象化といった他の概念も、堅牢で維持しやすいソフトウェアシステムを設計するために重要な役割を果たします。
Credits: Image by storyset