Class と継承を使いこなそう!

class

この記事では、Python のオブジェクト指向プログラミング(OOP)の基本である「Class(クラス)」と「継承(Inheritance)」について、初心者にもイメージしやすいように解説します。実際のコード例を交えながら学んでいきましょう。


1. オブジェクト指向プログラミング(OOP)とは?

まずは オブジェクト指向プログラミング(OOP) の基本概念から説明します。

  • オブジェクト:データ(属性)と処理(メソッド)をまとめたもの。
  • クラス:オブジェクトの設計図。どんな属性・メソッドを持つかを定義する。
  • インスタンス:クラスから生成された実体(オブジェクト)。

よりイメージしやすいように、レシピに例えてみると

  • クラス = レシピ(どんな材料が必要で、どう調理するか)
  • インスタンス = 実際に作った料理

レシピがあれば、同じ手順で何度でも料理を再現できますよね。クラスも同じく、「これを持っている・これができる」オブジェクトを何度でも作れる設計図になります。


2. Python でのクラス定義の基本

Python で最もシンプルなクラスの書き方を見てみましょう。

class Dog:
    # クラス変数(すべてのインスタンスで共有)
    species = "Canis familiaris"

    def __init__(self, name, age):
        # インスタンス変数(個々のインスタンス固有)
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name} says: ワンワン!")
  • __init__:インスタンス生成時に呼ばれる初期化メソッド。
  • self:インスタンス自身を指すキーワード。必ず第一引数に書きます。

インスタンス化してみよう

dog1 = Dog("ポチ", 3)
dog2 = Dog("ハチ", 5)

print(dog1.name, dog1.age)  # ポチ 3
print(dog2.name, dog2.age)  # ハチ 5

dog1.bark()  # ポチ says: ワンワン!
dog2.bark()  # ハチ says: ワンワン!

3. 継承(Inheritance)

ここからが本題の「継承」です。
継承とは、あるクラス(親クラス/スーパークラス)の機能を引き継いで、新しいクラス(子クラス/サブクラス)を作る仕組みです。

こちらも具体例でイメージをしましょう。

  1. 親クラス:自動車
  • エンジン、ホイール、ハンドル、といった基本的な部品と機能を持つ
  1. 子クラス:スポーツカー
  • 「自動車」をベースに「ターボエンジン」や「低重心シャーシ」などを追加

親クラスに書いた処理・属性はそのまま使え、必要に応じて追加や上書き(オーバーライド)も可能です。


4. Python での継承の書き方

先ほどの Dog クラスを親として、GuardDog(番犬)という子クラスを作ってみましょう。

class GuardDog(Dog):
    def __init__(self, name, age, guard_area):
        # super() で親クラスの __init__ を呼び出す
        super().__init__(name, age)
        self.guard_area = guard_area  # 子クラス独自の属性

    # 親クラスの bark をオーバーライド(上書き)
    def bark(self):
        print(f"{self.name} ({self.guard_area}) says: ガルルル…")

    # 子クラス独自のメソッド
    def guard(self):
        print(f"{self.name} is guarding {self.guard_area}!")
  • class GuardDog(Dog): で継承を指定。
  • super().__init__(…) で親クラスの初期化処理を呼び出します。
  • 必要に応じてメソッドを上書き(オーバーライド)したり、独自メソッドを追加できます。

動かしてみる

gd = GuardDog("タロー", 4, "倉庫")
print(gd.species)   # Canis familiaris(親から継承したクラス変数)
gd.bark()            # タロー (倉庫) says: ガルルル…
gd.guard()           # タロー is guarding 倉庫!

5. 継承のメリット

  1. コードの再利用
    親クラスに書いた機能をそのまま使えるので、同じ処理を何度も書かずに済みます。
  2. 保守性の向上
    基本機能は親クラスにまとめておくことで、バグ修正や機能追加を一か所で済ませられます。
  3. 拡張しやすい設計
    子クラスで必要な機能だけ追加・上書きすればよいので、新しい要件に柔軟に対応できます。

6. 継承時の注意点

  • 多重継承(複数の親クラスを持つ)は強力ですが、メソッド解決順序(MRO)が複雑になりやすいので慎重に。
  • オーバーライドしすぎない:親クラスと子クラスで同じメソッド名を多用すると、どの処理が呼ばれるか分かりにくくなることがあります。
  • super() の使い方:必ず正しい引数で呼び出し、親クラスの初期化を飛ばさないように注意しましょう。

7. 多重継承の例(応用編)

class Flyable:
    def fly(self):
        print("飛んでいます!")

class Swimmable:
    def swim(self):
        print("泳いでいます!")

# 多重継承クラス
class Duck(Flyable, Swimmable):
    def quack(self):
        print("ガーガー")
d = Duck()
d.quack()  # ガーガー
d.fly()    # 飛んでいます!
d.swim()   # 泳いでいます!

ポイント:Python の MRO によって、Duck がどのクラスからどのメソッドを取得するかが決まります。多重継承は便利ですが、複雑化しやすい点に注意しましょう。


8. 実践的な設計例:ゲームキャラクター

例えば RPG のキャラクターを設計する場合を考えてみます。

class Character:
    def __init__(self, name, hp):
        self.name = name
        self.hp = hp

    def attack(self, target):
        print(f"{self.name} attacks {target.name}!")

class Warrior(Character):
    def __init__(self, name, hp, strength):
        super().__init__(name, hp)
        self.strength = strength

    def attack(self, target):
        damage = self.strength * 2
        target.hp -= damage
        print(f"{self.name} の強力な攻撃! {target.name} に {damage} ダメージ!")

class Mage(Character):
    def __init__(self, name, hp, mp):
        super().__init__(name, hp)
        self.mp = mp

    def cast_spell(self, target):
        cost = 10
        if self.mp >= cost:
            self.mp -= cost
            target.hp -= 15
            print(f"{self.name} の魔法! {target.name} に 15 ダメージ!")
        else:
            print("MPが足りません!")
  • WarriorMage はともに Character を継承し、共通の namehpattack メソッドを持つ。
  • 個別の攻撃ロジック(物理 vs 魔法)を子クラスで定義しています。

9. 継承と組み合わせるデザインパターン

継承をさらに活かすため、よく使われるデザインパターンを紹介します。

  1. Template Method パターン
  • 親クラスで大まかな処理の流れ(テンプレート)を定義し、細かい実装は子クラスに任せる。
  1. Factory Method パターン
  • オブジェクト生成を親クラスに委譲し、子クラスで生成する具体的なクラスを決定する。
  1. Strategy パターン
  • アルゴリズムをクラスとして分離し、動的に差し替えられるようにする。

これらはいずれも「継承」と「ポリモーフィズム(多態性)」を活用した強力な手法です。


10. まとめと次の一歩

  • クラス は「設計図」、インスタンス は「実物」。
  • 継承 によってコードを再利用し、保守性・拡張性が向上する。
  • オーバーライドsuper() の使い方を正しく理解することが大切。
  • 多重継承デザインパターン によって、さらに柔軟で強力な設計が可能に。

これで Python の Class と継承の基本はマスターできました!ぜひご自分で小さなプロジェクトを作って、親子クラスの設計を試してみてください。


shota_py

メーカー勤務のエンジニアです。 自分の趣味である、「電気回路」、「ガジェット」「株式投資」、「Python」に関する記事をつらつらと書いています

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


ABOUT US
shota_py
メーカー勤務のエンジニアです。 自分の趣味である、「電気回路」、「ガジェット」「株式投資」、「Python」に関する記事をつらつらと書いています