オブジェクト指向プログラミングの強力な機能、「継承」と「オーバーライド」へようこそ!✨ これらをマスターすると、コードの再利用性が格段に上がり、より効率的で保守しやすいプログラムを書けるようになります。このステップで、その基本をしっかり学びましょう!
1. 継承 (Inheritance) とは? 🤔
継承とは、すでにあるクラス(親クラス または スーパークラス)の機能(属性やメソッド)を引き継いで、新しいクラス(子クラス または サブクラス)を作成する仕組みです。
例えるなら、乗り物という「親クラス」があり、その特徴(移動できる、定員があるなど)を引き継いで、自動車や自転車といった具体的な「子クラス」を作るようなイメージです。🚗🚲
継承のメリット:
- コードの再利用: 親クラスのコードをそのまま使えるので、同じようなコードを何度も書く必要がなくなります。
- 階層構造: クラス同士の関係性(is-a関係: 例「犬は動物である」)を明確に表現できます。
- 保守性の向上: 親クラスの修正が、それを継承するすべての子クラスに反映されるため、修正箇所が少なくなります。
基本的な書き方
Pythonでクラスを継承するには、クラス定義の際に括弧 ()
の中に親クラス名を指定します。
# 親クラスの定義
class Animal:
def __init__(self, name):
self.name = name
print(f"Animal {self.name} が生まれました。")
def eat(self):
print(f"{self.name} は食事をしています。")
# 子クラスの定義 (Animalクラスを継承)
class Dog(Animal): # 括弧の中に親クラス名を指定
def bark(self):
print(f"{self.name} はワン!と吠えています。")
# 子クラスのインスタンスを作成
my_dog = Dog("ポチ")
# 親クラスから継承したメソッドを使える
my_dog.eat()
# 子クラスで定義したメソッドも使える
my_dog.bark()
実行結果:
Animal ポチ が生まれました。
ポチ は食事をしています。
ポチ はワン!と吠えています。
Dog
クラスは Animal
クラスを継承しているので、Animal
で定義された __init__
メソッドや eat
メソッドをそのまま利用できます。
super() 関数: 親クラスのメソッドを呼び出す
子クラスで親クラスと同じ名前のメソッド(特に __init__
)を定義した場合、親クラスのメソッドは自動では呼ばれなくなります。親クラスのメソッドを明示的に呼び出したい場合は super()
関数を使います。
class Animal:
def __init__(self, name):
print("Animalの __init__ が呼ばれました。")
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
print("Dogの __init__ が呼ばれました。")
# super() を使って親クラス(Animal)の __init__ メソッドを呼び出す
super().__init__(name)
self.breed = breed # Dogクラス独自の属性を追加
print(f"犬種は {self.breed} です。")
def bark(self):
print(f"{self.name} はワン!")
my_dog = Dog("ハチ", "秋田犬")
print(f"犬の名前: {my_dog.name}")
実行結果:
Dogの __init__ が呼ばれました。
Animalの __init__ が呼ばれました。
犬種は 秋田犬 です。
犬の名前: ハチ
Dog
の __init__
内で super().__init__(name)
を呼び出すことで、Animal
の __init__
が実行され、self.name
属性が設定されています。
2. オーバーライド (Override) とは? 덮어쓰기
オーバーライドとは、親クラスから継承したメソッドを、子クラスで再定義することです。これにより、子クラス独自の振る舞いをさせることができます。
例えば、Animal
クラスに speak
メソッド(鳴く)があっても、動物の種類によって鳴き声は違いますよね?🐶🐱 Dog
クラスでは「ワン!」、Cat
クラスでは「ニャー!」と鳴くように、speak
メソッドをそれぞれのクラスでオーバーライドします。
オーバーライドのメリット:
- クラスごとのカスタマイズ: 同じメソッド名でも、クラスによって異なる処理を実行させることができます(ポリモーフィズム(多態性)の実現)。
- 柔軟性の向上: 基本的な動作は親クラスで定義し、具体的な動作は子クラスで調整できます。
基本的な書き方
オーバーライドは、子クラスで親クラスと同じ名前のメソッドを定義するだけです。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
# デフォルトの鳴き声 (子クラスでオーバーライドされることを期待)
print(f"{self.name} は...と鳴いています。")
class Dog(Animal):
# Animalクラスの speak メソッドをオーバーライド
def speak(self):
print(f"{self.name} はワン!と鳴いています。")
class Cat(Animal):
# Animalクラスの speak メソッドをオーバーライド
def speak(self):
print(f"{self.name} はニャー!と鳴いています。")
my_dog = Dog("ポチ")
my_cat = Cat("タマ")
my_dog.speak() # Dogクラスでオーバーライドされた speak が呼ばれる
my_cat.speak() # Catクラスでオーバーライドされた speak が呼ばれる
# Animalクラスのインスタンスも作ってみる
generic_animal = Animal("動物")
generic_animal.speak()
実行結果:
ポチ はワン!と鳴いています。
タマ はニャー!と鳴いています。
動物 は...と鳴いています。
Dog
と Cat
のインスタンスでは、それぞれのクラスでオーバーライド(再定義)された speak
メソッドが実行されています。
3. 継承とオーバーライドの組み合わせ例 🛠️
継承とオーバーライドは組み合わせて使うことで、その真価を発揮します。親クラスの共通機能は継承しつつ、子クラス固有の振る舞いをオーバーライドで実現しましょう。
ここでは、super()
を使って親クラスのメソッドを呼び出しつつ、子クラス独自の処理を追加する例を見てみましょう。
class Animal:
def __init__(self, name):
self.name = name
def greet(self):
print(f"こんにちは、私は {self.name} です。")
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__を呼び出してnameを設定
self.breed = breed
# 親クラスの greet メソッドをオーバーライド
def greet(self):
super().greet() # 親クラスの greet メソッドをまず呼び出す
# 子クラス独自の処理を追加
print(f"私の犬種は {self.breed} です。よろしくね!🐾")
my_dog = Dog("レオ", "ゴールデンレトリバー")
my_dog.greet()
実行結果:
こんにちは、私は レオ です。
私の犬種は ゴールデンレトリバー です。よろしくね!🐾
Dog
の greet
メソッドでは、まず super().greet()
で親クラスの挨拶を実行し、その後で犬種に関する情報を追加しています。このように、親クラスの機能を活用しつつ拡張することができます。
4. まとめ 📝
今回は、オブジェクト指向プログラミングにおける重要な概念である「継承」と「オーバーライド」について学びました。
- 継承: 親クラスの機能を引き継ぎ、コードの再利用性を高める。
class Child(Parent):
- オーバーライド: 親クラスから継承したメソッドを子クラスで再定義し、独自の振る舞いをさせる。
super()
: 子クラスから親クラスのメソッドを呼び出す際に使用する。
これらの概念を理解し使いこなすことで、より洗練された、構造化されたPythonプログラムを作成できるようになります。繰り返し練習して、ぜひ身につけてくださいね!💪
次は、オブジェクト指向のもう一つの重要な柱である「カプセル化」や、クラス変数・インスタンス変数について学んでいきましょう!
コメント