私は2つの用語と少し混乱しています、これが私が知っていることです:
ポリモーフィズムは、さまざまなタイプのオブジェクトが共通のインターフェースによって処理される能力です。ダックタイピングは、異なるタイプのオブジェクトが同じメソッドに応答できるようにする一種の動的タイピングです。
私が理解していることから、ポリモーフィズムとは、異なるクラス間で共有できるインターフェースを作成することです。そして、ダックタイピングは、メッセージの受信者にある限りメソッドを呼び出すことができるルーズタイピングに関するものです。
これは正しいです?私はこの2つについてかなり混乱しています。それらは関連しているように見えますが、それらの関係が何であるかはわかりません。よろしくお願いします!
ポリモーフィズム(オブジェクト指向プログラミングのコンテキストで)は、サブクラスが基本クラスのメソッドをオーバーライドできることを意味します。これは、クラスのメソッドがサブクラスでさまざまなことを実行できることを意味します。例:クラスAnimal
はメソッドtalk()
を持つことができ、サブクラスDog
とCat
のAnimal
はメソッドtalk()
異なる音を出します。
ダックタイピングは、コードが特定のメソッドを持つすべてのオブジェクトを単純に受け入れることを意味します。次のコードがあるとしましょう:animal.quack()
。指定されたオブジェクトanimal
に呼び出したいメソッドがある場合は、問題ありません(追加の型要件は必要ありません)。 animal
が実際にDuck
であるか、別の動物であるかどうかは関係ありません。それがダックタイピングと呼ばれる理由です。アヒルのように見える場合(たとえば、quack()
というメソッドがある場合、そのオブジェクトがアヒルであるかのように動作できます)。
それで、これらは関連していますか?これらは、プログラミング言語が持つ可能性のある別個の機能です。ポリモーフィズムはあるがダックタイピングがないプログラミング言語(Javaなど)があります。ポリモーフィズムとダックタイピングを備えた言語(Pythonなど)もあります。
これは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をオーバーライドしていることがわかります。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つの方法です。もう1つの方法は、静的型付けを使用することです。
長い答え:
ここには、タイピングとプログラミング手法という2つの異なる概念が含まれています。
ダックタイピングはタイピングの一種です。また、入力とは、渡されたオブジェクトが予期されたものではない場合にエラーをスローすることを意味しますwhen。ダックタイピングは、プログラムの実行中にエラーをスローし、呼び出されているメソッドが使用できないタイプのタイピングです。静的型付けにはコンパイル時のチェックが付属しているため、型情報が一致しない場合、コードのコンパイル時にエラーがスローされます。そしてそれはタイピングです。
ポリモーフィズムは、複数のタイプのオブジェクトが特定の責任を果たせるようにするプログラミング手法です。これを行うには、基本タイプを使用してすべての子クラスタイプを表します。ダックタイピングを使用して、必要なメソッドを持つすべての異なるタイプを表すことができます。インターフェイスを使用して、インターフェイスを実装するすべてのタイプを表すことができます。
ポリモーフィズムは継承であるという答えがありますが、それは正しくありません。継承を使用してポリモーフィックな動作を作成することはできますが、通常はそれを行いますが、それはポリモーフィズムの目的ではありません。
1つは、上記のようにポリモーフィズムを持つために継承は必要ありません。
第二に、「ポリモーフィズム」という用語は、実装コードではなく、抽象化に依存するクライアントコードのコンテキストでより意味があります。スーパークラスとそれを継承する他のいくつかのクラスがあり、いくつかのメソッドをオーバーライドするからといって、それがポリモーフィズムであることを意味するわけではありません。ポリモーフィズムを作成するには、これらのクラスを消費するポリモーフィックな方法でクライアントコードを作成する必要があります。