web-dev-qa-db-ja.com

ポリモーフィズムとダックタイピングの違いは何ですか?

私は2つの用語と少し混乱しています、これが私が知っていることです:

ポリモーフィズムは、さまざまなタイプのオブジェクトが共通のインターフェースによって処理される能力です。ダックタイピングは、異なるタイプのオブジェクトが同じメソッドに応答できるようにする一種の動的タイピングです。

私が理解していることから、ポリモーフィズムとは、異なるクラス間で共有できるインターフェースを作成することです。そして、ダックタイピングは、メッセージの受信者にある限りメソッドを呼び出すことができるルーズタイピングに関するものです。

これは正しいです?私はこの2つについてかなり混乱しています。それらは関連しているように見えますが、それらの関係が何であるかはわかりません。よろしくお願いします!

31
gerky

ポリモーフィズム(オブジェクト指向プログラミングのコンテキストで)は、サブクラスが基本クラスのメソッドをオーバーライドできることを意味します。これは、クラスのメソッドがサブクラスでさまざまなことを実行できることを意味します。例:クラスAnimalはメソッドtalk()を持つことができ、サブクラスDogCatAnimalはメソッドtalk()異なる音を出します。

ダックタイピングは、コードが特定のメソッドを持つすべてのオブジェクトを単純に受け入れることを意味します。次のコードがあるとしましょう:animal.quack()。指定されたオブジェクトanimalに呼び出したいメソッドがある場合は、問題ありません(追加の型要件は必要ありません)。 animalが実際にDuckであるか、別の動物であるかどうかは関係ありません。それがダックタイピングと呼ばれる理由です。アヒルのように見える場合(たとえば、quack()というメソッドがある場合、そのオブジェクトがアヒルであるかのように動作できます)。

それで、これらは関連していますか?これらは、プログラミング言語が持つ可能性のある別個の機能です。ポリモーフィズムはあるがダックタイピングがないプログラミング言語(Javaなど)があります。ポリモーフィズムとダックタイピングを備えた言語(Pythonなど)もあります。

31
Simeon Visser

これはPythonのポリモーフィズムの例です。

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Cat('Mr. Mistoffelees'),
           Dog('Lassie')]

for animal in animals:
    print animal
    print animal.name + ': ' + animal.talk()

これは、Pythonでのダックタイピングの例です。

class Duck:
    def quack(self):
        print("Quaaaaaack!")
    def feathers(self):
        print("The duck has white and gray feathers.")
    def name(self):
        print("ITS A DUCK NO NAME")


class Person:
    def quack(self):
        print("The person imitates a duck.")
    def feathers(self):
        print("The person takes a feather from the ground and shows it.")
    def name(self):
        print("John Smith")

def in_the_forest(duck):
    duck.quack()
    duck.feathers()
    duck.name()

def game():
    for element in [ Duck() , Person()]:
        in_the_forest(element)

game()
  • ポリモーフィズムでは、サブクラス(CatおよびDog)が親クラス(Animal)から継承し、メソッドTalkをオーバーライドしていることがわかります。
  • ダックタイピングの場合、サブクラスは作成しません。代わりに、同じ名前で機能が異なるメソッドを使用して新しいクラスを作成します。
10
Prakash D

2つのタイプのポリモーフィズム

  1. メソッドのオーバーロード(コンパイル時のポリモーフィズム)。
  2. メソッドのオーバーライド(ランタイムポリモーフィズム)。

メソッドのオーバーロード:-同じ関数名と異なるデータ型はメソッドのオーバーロードと呼ばれます

例:

  int addTwovalues(int a, int b)
  { return (a+b)}

  float addTwovalues(float a, float b)
  { return (a+b)}

  Method overriding :- same function name and same data type but different Class
     is known as       Method overriding.


  class a
 {
  virtual int addtwovalues()
   {  // to do  }
  }
 class b:a
 {
     override int addtwovalues()
   {  // to do  }

  }



  a obj=new a();
  obj.addtwovalues();

  b objb=new a();
  objb.addtwovalues();  //run time Polymorphism 
1
Prasad KM

短い答え:

ダックタイピングは、ポリモーフィズムを実現する1つの方法です。もう1つの方法は、静的型付けを使用することです。

長い答え:

ここには、タイピングとプログラミング手法という2つの異なる概念が含まれています。

ダックタイピングはタイピングの一種です。また、入力とは、渡されたオブジェクトが予期されたものではない場合にエラーをスローすることを意味しますwhen。ダックタイピングは、プログラムの実行中にエラーをスローし、呼び出されているメソッドが使用できないタイプのタイピングです。静的型付けにはコンパイル時のチェックが付属しているため、型情報が一致しない場合、コードのコンパイル時にエラーがスローされます。そしてそれはタイピングです。

ポリモーフィズムは、複数のタイプのオブジェクトが特定の責任を果たせるようにするプログラミング手法です。これを行うには、基本タイプを使用してすべての子クラスタイプを表します。ダックタイピングを使用して、必要なメソッドを持つすべての異なるタイプを表すことができます。インターフェイスを使用して、インターフェイスを実装するすべてのタイプを表すことができます。

ポリモーフィズムは継承であるという答えがありますが、それは正しくありません。継承を使用してポリモーフィックな動作を作成することはできますが、通常はそれを行いますが、それはポリモーフィズムの目的ではありません。

1つは、上記のようにポリモーフィズムを持つために継承は必要ありません。

第二に、「ポリモーフィズム」という用語は、実装コードではなく、抽象化に依存するクライアントコードのコンテキストでより意味があります。スーパークラスとそれを継承する他のいくつかのクラスがあり、いくつかのメソッドをオーバーライドするからといって、それがポリモーフィズムであることを意味するわけではありません。ポリモーフィズムを作成するには、これらのクラスを消費するポリモーフィックな方法でクライアントコードを作成する必要があります。

1
Andy