開発者ドキュメント

Python3のクラスにポリモーフィズムを適用する方法

序章

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

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

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

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

前提条件

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

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

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

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

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

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

多態的なクラスの作成

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

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

作成します 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.")

上記のコードでは、両方 SharkClownfish クラスには、共通の同じ名前の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()

2つのオブジェクトがあります。 sammyShark クラス、および caseyClownfish クラス。 私たちの 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.

The for ループは最初に繰り返されます sammy のインスタンス化 Shark クラス、次に casey のオブジェクト Clownfish クラスなので、に関連するメソッドが表示されます Shark 最初にクラス、次に Clownfish クラス。

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

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

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

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

polymorphic_fish.py
def in_the_pacific(fish):

次に、関数に、 fish 渡したオブジェクト。 この場合、 swim() それぞれが2つのクラスで定義されているメソッド SharkClownfish:

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

次に、両方のインスタンス化を作成します SharkClownfish まだ持っていない場合はクラス。 それらで、私たちは同じものを使用して彼らの行動を呼び出すことができます 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 クラス。 The casey と呼ばれるオブジェクト swim() で定義されたメソッド Clownfish クラス、および sammy と呼ばれるオブジェクト swim() で定義されたメソッド Shark クラス。

結論

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

モバイルバージョンを終了