🔖

プログラミングで耳にする「ポリモーフィズム」をちゃんと理解しようと試行錯誤してみたら、自分のコードにも活かせることがわかった話

2025/01/31に公開

最近、オブジェクト指向プログラミングの基本である「ポリモーフィズム」という言葉を耳にする機会が増えました。普段の開発でも使っている気はするものの、「これって何が特別なんだろう?」と思う場面も。

そこで今回は、ポリモーフィズムについて調べ、理解したことを皆さんと共有したいと思います。これから学ぶ方や「なんとなく使ってるけどよくわからない」という方の参考になれば幸いです。


ポリモーフィズムって何?簡単に言うとこういうこと

ポリモーフィズム(多態性)は、「異なる型のオブジェクトが共通の操作を共有できること」と言われています。
例えば、動物をテーマにしたプログラムを考えてみましょう。犬、猫、鳥というクラスがそれぞれ「鳴く」という動作を持つとします。ポリモーフィズムを活用すると、それらを「動物」として一括りにし、「鳴く」という動作を共通のインターフェースとして扱えるようになります。

Pythonでの例を挙げると、こんな感じです。

class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        return "ワンワン"

class Cat(Animal):
    def make_sound(self):
        return "ニャーニャー"

class Bird(Animal):
    def make_sound(self):
        return "ピヨピヨ"

def animal_sound(animal: Animal):
    print(animal.make_sound())

# 実行
dog = Dog()
cat = Cat()
bird = Bird()

animal_sound(dog)  # ワンワン
animal_sound(cat)  # ニャーニャー
animal_sound(bird) # ピヨピヨ

このコードでは、「動物」という抽象的なカテゴリを使って、それぞれの具体的な動物が異なる振る舞いをすることができます。これがポリモーフィズムの基本的な考え方です。

ポリモーフィズムのどこが大事なの?

1. コードの再利用性が高まる

ポリモーフィズムを使うと、異なるクラスが共通の操作を共有できるので、コードの再利用性が格段に向上します。
たとえば、もし新しい動物(例えば「象」)を追加しても、既存の animal_sound 関数を変更する必要はありません。象クラスに make_sound メソッドを実装するだけで対応できます。

2. 変更に強い設計が可能

大規模なシステムでは、仕様変更や機能追加が頻繁に発生します。ポリモーフィズムを活用することで、既存のコードに手を加えず、新しい機能を柔軟に追加することができます。これにより、保守性が高まります。

3. 抽象化による汎用性の向上

ポリモーフィズムは「抽象的な操作」を中心にコードを設計することを促進します。この結果、異なる型のオブジェクトを統一的に扱える汎用性の高いコードが書けるようになります。

ポリモーフィズムがないとどうなる?

もしポリモーフィズムを使わずにすべての動物の「鳴く」動作を実装しようとすると、次のようなコードになるかもしれません。

def make_animal_sound(animal_type, animal_name):
    if animal_type == "dog":
        print(f"{animal_name} はワンワンと鳴きます")
    elif animal_type == "cat":
        print(f"{animal_name} はニャーニャーと鳴きます")
    elif animal_type == "bird":
        print(f"{animal_name} はピヨピヨと鳴きます")
    else:
        print(f"{animal_name} は未知の鳴き声を持っています")

  • 新しい動物を追加するたびに、make_animal_sound 関数に新しい条件分岐を追加する必要があります。
  • このようなコードは「スパゲティコード」になりやすく、保守性が低下します。

ポリモーフィズムを活用することで、こういった分岐の煩雑さから解放され、シンプルで直感的なコードが実現できます。

ポリモーフィズムの現実世界での活用例

支払い処理システム

たとえば、ECサイトで異なる支払い方法を扱う場合、次のようにポリモーフィズムを活用できます。

class Payment:
    def pay(self, amount):
        pass

class CreditCardPayment(Payment):
    def pay(self, amount):
        print(f"クレジットカードで {amount} 円を支払いました")

class PaypalPayment(Payment):
    def pay(self, amount):
        print(f"PayPalで {amount} 円を支払いました")

class BitcoinPayment(Payment):
    def pay(self, amount):
        print(f"ビットコインで {amount} 円を支払いました")

def process_payment(payment: Payment, amount: int):
    payment.pay(amount)

# 支払いを処理
process_payment(CreditCardPayment(), 1000)
process_payment(PaypalPayment(), 2000)
process_payment(BitcoinPayment(), 3000)

新しい支払い方法を追加する際も、process_payment 関数を変更する必要はありません。

学んだこととこれからの活用

今回、ポリモーフィズムについて学んでみて、普段何気なく使っているコードの裏にある考え方を改めて理解することができました。一見「当たり前」に見える動作でも、その背景には「変更に強い設計」「汎用性の高いコード」という設計の意図があることがわかりました。

特に大規模なプロジェクトでは、こうした基本的な概念をしっかり理解して活用することで、保守性や拡張性の高いシステムを作ることができると感じました。

まとめ

ポリモーフィズムは、コードの再利用性や拡張性を高めるための強力なツールです。名前だけを聞くと難しそうですが、実際にはとてもシンプルな概念でした。
今後も、こういった基本的な概念を意識しながら、自分のコードに活かしていきたいと思います。そして、まだまだ勉強中の身ですので、みなさんと一緒に理解を深めていけたら嬉しいです。

Discussion