我对这两个术语有些困惑,这是我所知道的:
多态性是指不同类型的对象能够被一个共同的接口处理的能力。而鸭子类型则是一种动态类型,它允许不同类型的对象响应相同的方法。
据我所理解,多态性更多地关注于创建可在不同类之间共享的接口。而鸭子类型则是关注于松散的类型,只要该方法存在于消息的接收者上,就允许调用该方法。
这样说对吗?我对这两个概念感到有些困惑,它们似乎有关联,但我不知道它们之间的具体关系。非常感谢!
我对这两个术语有些困惑,这是我所知道的:
多态性是指不同类型的对象能够被一个共同的接口处理的能力。而鸭子类型则是一种动态类型,它允许不同类型的对象响应相同的方法。
据我所理解,多态性更多地关注于创建可在不同类之间共享的接口。而鸭子类型则是关注于松散的类型,只要该方法存在于消息的接收者上,就允许调用该方法。
这样说对吗?我对这两个概念感到有些困惑,它们似乎有关联,但我不知道它们之间的具体关系。非常感谢!
Animal
类可以有一个 talk()
方法,而 Animal
的子类 Dog
和 Cat
可以让方法 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。简短回答:
鸭子类型是实现多态的一种方式。另一种方式是使用静态类型。
详细回答:
这里涉及到两个不同的概念,类型和编程技术。
鸭子类型是一种类型。而类型意味着在传递了一个不符合预期的对象时,何时抛出错误。鸭子类型是一种类型,在程序运行时调用的方法不可用时会抛出错误。静态类型具有编译时检查的功能,因此如果类型信息不匹配,在编译代码时会抛出错误,这就是类型。
多态是一种编程技术,您允许多种类型的对象来完成某些职责。您可以使用基类型表示所有子类类型。您可以使用鸭子类型来表示具有所需方法的所有不同类型。您可以使用接口表示实现接口的所有类型。
有些答案称多态是继承,这是不正确的。尽管您可以使用继承来创建多态行为,通常也是这样做的,但这不是多态的核心。
首先,您不需要继承来实现上述多态。
其次,“多态”一词在依赖抽象的客户端代码上下文中更有意义,而不是在实现代码中。仅仅因为你有一个超类和几个从它继承且覆盖一些方法的子类,并不意味着它是多态的。要创建多态性,您必须以多态方式编写客户端代码来使用这些类。
两种多态性
方法重载:相同的函数名称和不同的数据类型被称为方法重载
例如:
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
add(int x, int y)
和一个名为add(String s, String t)
的函数,这两个函数具有相同的名称,但实际参数确定了调用哪个函数。 - Simeon VisserFoo
可用于鸭子类型,并且每个类都实现了接口IFoo
,那么多态或鸭子类型可以相互实现;而且如果每个想要公开多态方法集的类都有一个具有已知名称的成员变量来返回实现这些方法的包装器,则也可以相互实现。 - supercat