序章

ポリモーフィズムは、データ型クラスなどのさまざまな基になるフォームに同じインターフェイスを活用する機能です。 これにより、関数はさまざまなタイプのエンティティをさまざまな時間に使用できます。

Pythonでのオブジェクト指向プログラミングの場合、これは、特定のクラスに属する特定のオブジェクトを、別のクラスに属する別のオブジェクトであるかのように使用できることを意味します。

ポリモーフィズムにより、柔軟性と緩い結合が可能になるため、コードを拡張して、長期にわたって簡単に保守できます。

このチュートリアルでは、Pythonのクラスにポリモーフィズムを適用する方法について説明します。

前提条件

Python 3をインストールし、コンピューターまたはサーバーにプログラミング環境をセットアップする必要があります。 プログラミング環境をセットアップしていない場合は、ローカルプログラミング環境またはサーバー上のプログラミング環境のインストールおよびセットアップガイドを参照して、オペレーティングに適したものにすることができます。システム(Ubuntu、CentOS、Debianなど)

ポリモーフィズムとは何ですか?

ポリモーフィズムはPythonのクラス定義の重要な機能であり、クラスまたはサブクラス間でメソッドに共通の名前を付ける場合に使用されます。 これにより、関数は、クラス間の違いを意識することなく、これらのポリモーフィッククラスのオブジェクトを使用できます。

ポリモーフィズムは、継承を介して実行でき、サブクラスは基本クラスのメソッドを使用するか、それらをオーバーライドします。

Pythonのダックタイピングは、動的型付けの特殊なケースであり、遅延バインディング動的ディスパッチャなどのポリモーフィズムに特徴的な手法を使用します。 「ダックタイピング」という用語は、作家のジェームズウィットコムライリーの言葉に由来しています。「アヒルのように歩き、アヒルのように泳ぎ、アヒルのように鳴く鳥を見ると、その鳥をアヒルと呼びます。」 comp.lang.pythonニュースグループへのメッセージでイタリアのコンピューターエンジニアAlexMartelliによって流用されたダックタイピングの使用は、特定の目的に対するオブジェクトの適合性の確立に関係しています。 通常のタイピングを使用する場合、この適合性はオブジェクトのタイプのみによって決定されますが、ダックタイピングでは、問題のオブジェクトの実際のタイプではなく、メソッドとプロパティの存在が適合性を決定するために使用されます。 つまり、オブジェクトアヒルであるかどうかを確認するのではなく、オブジェクトがアヒルのように鳴き、アヒルのように歩くかどうかを確認します。

複数のクラスまたはサブクラスが同じメソッド名を持っているが、これらの同じメソッドの実装が異なる場合、クラスは、異なるタイプのエンティティで使用する単一のインターフェイスを使用しているため、ポリモーフィックです。 関数は、呼び出されるクラスを知らなくても、これらのポリモーフィックメソッドを評価できます。

ポリモーフィッククラスの作成

ポリモーフィズムを利用するために、2つの異なるオブジェクトで使用する2つの異なるクラスを作成します。 これらの個別のクラスはそれぞれ、多態的に使用できるように共通のインターフェイスを備えている必要があるため、個別であるが同じ名前のメソッドを提供します。

情報:このチュートリアルのサンプルコードに従うには、python3コマンドを実行して、ローカルシステムでPythonインタラクティブシェルを開きます。 次に、>>>プロンプトの後に例を追加して、例をコピー、貼り付け、または編集できます。

SharkクラスとClownfishクラスを作成します。それぞれが、swim()swim_backwards()、およびskeleton()のメソッドを定義します。 。

polymorphic_fish.py
class Shark():
    def swim(self):
        print("The shark is swimming.")

    def swim_backwards(self):
        print("The shark cannot swim backwards, but can sink backwards.")

    def skeleton(self):
        print("The shark's skeleton is made of cartilage.")


class Clownfish():
    def swim(self):
        print("The clownfish is swimming.")

    def swim_backwards(self):
        print("The clownfish can swim backwards.")

    def skeleton(self):
        print("The clownfish's skeleton is made of bone.")

上記のコードでは、SharkクラスとClownfishクラスの両方に、同じ名前の3つのメソッドが共通しています。 ただし、これらのメソッドの各機能はクラスごとに異なります。

これらのクラスを2つのオブジェクトにインスタンス化してみましょう。

polymorphic_fish.py
...
sammy = Shark()
sammy.skeleton()

casey = Clownfish()
casey.skeleton()

python polymorphic_fish.pyコマンドを使用してプログラムを実行すると、各オブジェクトが期待どおりに動作することがわかります。

Output
The shark's skeleton is made of cartilage. The clownfish's skeleton is made of bone.

共通のインターフェースを使用する2つのオブジェクトができたので、個々のタイプに関係なく、2つのオブジェクトを同じように使用できます。

クラスメソッドによるポリモーフィズム

Pythonがこれらの異なるクラスタイプのそれぞれを同じように使用する方法を示すために、最初に、オブジェクトのタプルを反復するforループを作成できます。 そうすれば、各オブジェクトがどのクラスタイプであるかを気にせずに、メソッドを呼び出すことができます。 これらのメソッドが実際に各クラスに存在すると想定するだけです。

polymorphic_fish.py
...
sammy = Shark()

casey = Clownfish()

for fish in (sammy, casey):
    fish.swim()
    fish.swim_backwards()
    fish.skeleton()

SharkクラスのsammyClownfishクラスのcaseyの2つのオブジェクトがあります。 forループは、これらのオブジェクトを繰り返し処理し、それぞれでswim()swim_backwards()、およびskeleton()メソッドを呼び出します。

プログラムを実行すると、出力は次のようになります。

Output
The shark is swimming. The shark cannot swim backwards, but can sink backwards. The shark's skeleton is made of cartilage. The clownfish is swimming. The clownfish can swim backwards. The clownfish's skeleton is made of bone.

forループは、最初にSharkクラスのsammyインスタンス化を繰り返し、次にClownfishクラスのcaseyオブジェクトを繰り返しました。最初にSharkクラスに関連するメソッドを参照し、次にClownfishクラスを参照してください。

これは、Pythonがこれらの各オブジェクトがどのクラスタイプであるかを正確に知らない、または気にしない方法でこれらのメソッドを使用していることを示しています。 つまり、これらのメソッドを多態的に使用します。

関数を持つポリモーフィズム

また、任意のオブジェクトを取得できる関数を作成して、ポリモーフィズムを可能にすることもできます。

fishを呼び出すことができるオブジェクトを取り込むin_the_pacific()という関数を作成しましょう。 fishという名前を使用していますが、インスタンス化されたオブジェクトはすべて、この関数に呼び出すことができます。

polymorphic_fish.py
def in_the_pacific(fish):

次に、渡したfishオブジェクトを使用する関数を実行します。 この場合、swim()メソッドを呼び出します。各メソッドは、SharkClownfishの2つのクラスで定義されています。

polymorphic_fish.py
...
def in_the_pacific(fish):
    fish.swim()

次に、SharkクラスとClownfishクラスの両方のインスタンス化を、まだ作成していない場合は作成します。 これらを使用すると、同じin_the_pacific()関数を使用してアクションを呼び出すことができます。

polymorphic_fish.py
...
def in_the_pacific(fish):
    fish.swim()

sammy = Shark()

casey = Clownfish()

in_the_pacific(sammy)
in_the_pacific(casey)

プログラムを実行すると、出力は次のようになります。

Output
The shark is swimming. The clownfish is swimming.

ランダムオブジェクト(fish)を定義するときにin_the_pacific()関数に渡しましたが、それでもSharkClownfishクラス。 Clownfishクラスで定義されたswim()メソッドと呼ばれるcaseyオブジェクト、およびswim()メソッドで定義されたsammyオブジェクトX149X]