Python OOP ポリモーフィズム: ダック タイピングとインターフェイス

Python でポリモーフィズムをマスターします。ダックタイピング、メソッドのオーバーライド、抽象基本クラスを使用して、柔軟で疎結合なコードを作成する方法を学びます。

エディターで試してみる

概要

ポリモーフィズムとは、「多くの形式」を意味するギリシャ語です。オブジェクト指向プログラミングでは、異なるクラスが独自の方法で同じメソッド呼び出しに応答する機能を指します。ポリモーフィズムを使用すると、共通のインターフェイスを共有している場合に限り、さまざまな種類のオブジェクトを処理できる単一の関数を作成できます。これにより、低結合が可能になり、ソフトウェア システムの適応性が高く、拡張が容易になります。

Python では、ポリモーフィズムはダック タイピングとして知られる概念と深く結びついています。この用語は、「アヒルのように歩き、アヒルのように鳴くなら、それはアヒルに違いない」というフレーズから来ています。動的に型指定された Python では、関数はオブジェクトがどのクラスに属しているかを気にしません。そのオブジェクトが要求されたメソッドを実装しているかどうかだけが考慮されます。たとえば、`.speak()` を呼び出す関数がある場合、それに Dog、Cat、または Robot を渡すことができます。それらすべてに `.speak()` メソッドがある限り、コードは完全に実行されます。

より厳密なアーキテクチャの場合、Python は組み込みの `abc` モジュールを介して抽象基本クラス (ABC) を提供します。 `abc.ABC` から継承し、`@abstractmethod` デコレータを使用することにより、子クラスが強制的に実装する正式なインターフェイスを定義できます。子クラスが抽象メソッドの定義に失敗した場合、インスタンス化しようとすると Python は TypeError を発生させます。柔軟なダックタイピングと正式な抽象クラスのバランスを取ることは、回復力のある Python ライブラリを設計するための重要なスキルです。

コードと実行の出力

面積を計算する形状を表す多態性クラスを実装します。

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        """Must be implemented by subclasses."""
        pass

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

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        import math
        return math.pi * (self.radius ** 2)

# Polymorphic function accepting any Shape
def print_area(shape: Shape):
    print(f"Calculated Area: {shape.area():.2f}")

print_area(Square(4))
print_area(Circle(3))
端子出力
Calculated Area: 16.00
Calculated Area: 28.27

段階的な実装

  • CreditCard、PayPal、および Stripe オブジェクトを処理する支払いプロセッサの作成
  • 統合されたレンダリング ループを使用してさまざまな要素 (テキスト、画像) を描画する
  • 単体テスト中の外部 API 接続のモック化

よくある質問

アヒルタイピングとは何ですか?

これは、ポリモーフィズムに対する Python の動的なアプローチです。特定の親クラスからの継承を検証するのではなく、実行時にメソッドとプロパティの存在をチェックします。

抽象基本クラスをインスタンス化できますか?

いいえ。ABC から継承し、抽象メソッドを含むクラスをインスタンス化しようとすると、TypeError が発生します。

関連トピック

推奨される Python リソース

関連するインタラクティブなチュートリアル、チートシート、コード比較で知識を深めてください。