前書き

*多態性*は、https://www.digitalocean.com/community/tutorials/understanding-data-types-in-python-3 [data types]やhttps:/など、さまざまな基礎となるフォームに対して同じインターフェイスを活用する機能です。 /www.digitalocean.com/community/tutorials/how-to-construct-classes-and-define-objects-in-python-3[classes]。 これにより、https://www.digitalocean.com/community/tutorials/how-to-define-functions-in-python-3 [functions]が異なるタイプのエンティティを異なる時間に使用できるようになります。

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

多態性により、柔軟性と疎結合が可能になるため、コードを拡張し、長期にわたって容易に維持できます。

このチュートリアルでは、Pythonのクラスにポリモーフィズムを適用します。

多型とは

ポリモーフィズムはPythonのクラス定義の重要な機能であり、クラスまたはサブクラス全体で一般的に名前の付いたメソッドがある場合に利用されます。 これにより、クラス全体の違いを意識する必要なく、関数はこれらの多態性クラスのオブジェクトを使用できます。

ポリモーフィズムはhttps://www.digitalocean.com/community/tutorials/understanding-inheritance-in-python-3[inheritance]を介して実行でき、サブクラスは基本クラスメソッドを使用するか、オーバーライドします。

ダイナミックタイピングの特殊なケースであるPythonの*ダックタイピング*では、https://en.wikipedia.org/wiki/Late_binding [late binding]やhttps://en.wikipedia.org/wiki/を含む、ポリモーフィズムに特徴的な手法を使用しています。 Dynamic_dispatch [動的ディスパッチ]。 「アヒルのタイピング」という用語は、作家のジェームズ・ホイットコム・ライリーの引用に由来します。 comp.lang.pythonニュースグループへのメッセージの中でコンピューターエンジニアのAlex Martelliが、アヒルタイピングの使用は、特定の目的に対するオブジェクトの適合性の確立に関係しています。 通常のタイピングを使用する場合、この適合性はオブジェクトのタイプのみによって決定されますが、アヒルのタイピングでは、問題のオブジェクトの実際のタイプではなくメソッドとプロパティの存在が使用されます。 つまり、オブジェクトがアヒルであるかどうかを尋ねるのではなく、オブジェクトがアヒルのように鳴り、アヒルのように歩くかどうかを確認します。

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

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

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

+ 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 +`コマンドでプログラムを実行すると、各オブジェクトが期待どおりに動作することがわかります。

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

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

クラスメソッドを使用した多態性

Pythonがこれらの異なるクラスタイプのそれぞれを同じ方法で使用する方法を示すために、まずhttps://www.digitalocean.com/community/tutorials/how-to-construct-for-loops-in-python-を作成できます3 [`+ for +`ループ] tupleのオブジェクトを反復処理します。 その後、各オブジェクトがどのクラス型であるかを気にせずにメソッドを呼び出すことができます。 これらのメソッドが実際に各クラスに存在することのみを想定します。

polymorphic_fish.py

...
sammy = Shark()

casey = Clownfish()

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

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

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

OutputThe 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がこれらの各オブジェクトがどのクラス型であるかを正確に知らない、または気にせずにこれらのメソッドを使用していることを示しています。 つまり、これらのメソッドを多態的に使用します。

関数を使用した多態性

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

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

polymorphic_fish.py

…
def in_the_pacific(fish):

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

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)

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

OutputThe shark is swimming.
The clownfish is swimming.

ランダムオブジェクト( + fish +)を定義するときに `+ in_the_pacific()`関数に渡しましたが、 ` Shark `および ` Clownfish `クラスのインスタンス化のためにそれを効果的に使用することができました。 ` casey `オブジェクトは ` Clownfish `クラスで定義された ` swim()`メソッドを呼び出し、 ` sammy `オブジェクトは ` Shark `クラスで定義された ` swim()+`メソッドを呼び出しました。

結論

さまざまなオブジェクトがポリモーフィズムを介して同様の方法で関数とメソッドを活用できるようにすることで、このPython機能を使用すると、オブジェクト指向コードの柔軟性と拡張性が向上します。