TechCraft – エンジニアのためのスキルアップメモ

エンジニアのスキルアップを少しでも加速する技術ブログ

Pythonで学ぶポリモーフィズム

Pythonで学ぶポリモーフィズムオブジェクト指向の基礎を楽しく理解しよう

オブジェクト指向プログラミング(OOP)の三大要素といえば、「カプセル化」「継承」「ポリモーフィズム」です。その中でもポリモーフィズム多態性は、柔軟で再利用性の高いコードを書くために非常に重要な概念です。

本記事では、Pythonにおけるポリモーフィズムの基本から応用までを、実例を交えてわかりやすく解説します。


1. ポリモーフィズムとは?

定義

ポリモーフィズム(Polymorphism)とは、「異なる型のオブジェクトが、同じインターフェースで扱えること」を意味します。つまり、同じメソッド名で、異なるクラスのオブジェクトに異なる振る舞いを持たせることができる仕組みです。


2. Pythonにおけるポリモーフィズムの種類

ポリモーフィズムの種類 概要
サブクラスによるポリモーフィズム 継承を使って、基底クラスのメソッドをオーバーライド
Duck Typing 実際の型に関係なく、振る舞い(インターフェース)で判断
抽象基底クラス(ABC) 型安全なポリモーフィズムを明示的に指定可能

3. 基本例:動物クラスで学ぶポリモーフィズム

class Animal:
    def speak(self):
        print("何か話すよ")

class Dog(Animal):
    def speak(self):
        print("ワンワン!")

class Cat(Animal):
    def speak(self):
        print("ニャーニャー!")

def animal_speak(animal):
    animal.speak()

# ポリモーフィズムの例
animals = [Dog(), Cat(), Animal()]
for a in animals:
    animal_speak(a)

出力結果:

ワンワン!
ニャーニャー!
何か話すよ

animal_speak() 関数は、どのクラスであっても .speak() を呼ぶだけですが、クラスごとに異なる動作が行われます。


4. Duck Typingの例:Pythonポリモーフィズム

class Bird:
    def fly(self):
        print("鳥が飛ぶ")

class Airplane:
    def fly(self):
        print("飛行機が飛ぶ")

def take_off(flyable):
    flyable.fly()

# fly() を持っていればどんなオブジェクトでもOK
take_off(Bird())
take_off(Airplane())

Pythonは静的型チェックがないため、「fly()があればOK」という柔軟な設計ができます。


5. 抽象基底クラス(ABC)による型明示

Python 3.4以降は、abcモジュールを使って明示的なインターフェース(抽象クラス)も定義できます。

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, r):
        self.r = r

    def area(self):
        return 3.14 * self.r * self.r

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side * self.side

shapes = [Circle(5), Square(4)]
for s in shapes:
    print(s.area())

Shape クラスはインターフェースの役割を果たし、派生クラスはその実装を提供します。


6. ポリモーフィズムの活用パターン

1. 複数のアルゴリズムの切り替え

class JSONSerializer:
    def serialize(self, data):
        import json
        return json.dumps(data)

class XMLSerializer:
    def serialize(self, data):
        return f"<data>{data}</data>"

def save(data, serializer):
    print(serializer.serialize(data))

save({"name": "Alice"}, JSONSerializer())
save("Bob", XMLSerializer())

2. GUIウィジェットやゲームオブジェクトの描画処理

class Button:
    def draw(self):
        print("Draw Button")

class TextBox:
    def draw(self):
        print("Draw TextBox")

for widget in [Button(), TextBox()]:
    widget.draw()

7. まとめ

  • Pythonポリモーフィズムを自然な形で実現できる言語です
  • 継承だけでなく、Duck Typing抽象クラス(ABC)も活用できます
  • 実際の開発では、柔軟で拡張しやすいアーキテクチャを作るための基礎となります

参考リンク

参考書籍