36

我对这两个术语有点困惑,这就是我所知道的:

多态性是不同类型的对象由一个公共接口处理的能力。而鸭子类型,是一种动态类型,它允许不同类型的对象响应相同的方法。

据我了解,多态更多的是创建一个可以跨不同类共享的接口。鸭子类型是关于松散类型的,只要在消息的接收者上找到方法,就可以调用它。

它是否正确?我对这两个很困惑,他们似乎有关系,但我不知道他们的关系是什么。提前非常感谢!

4

4 回答 4

37

多态性(在面向对象编程的上下文中)意味着子类可以覆盖基类的方法。这意味着一个类的方法可以在子类中做不同的事情。例如:一个类Animal可以有一个方法talk(),子类DogCatofAnimal可以让方法talk()发出不同的声音。

鸭子类型意味着代码将简单地接受具有特定方法的任何对象。假设我们有以下代码:animal.quack(). 如果给定的对象animal有我们想要调用的方法,那么我们很好(不需要额外的类型要求)。是否animal实际上是一种Duck或另一种也碰巧会嘎嘎的动物并不重要。这就是它被称为鸭子类型的原因:如果它看起来像一只鸭子(例如,它有一个被调用的方法,quack()那么我们可以像该对象是一只鸭子一样行事)。

那么这些有关系吗?它们只是编程语言可能具有的单独功能。有些编程语言具有多态性但没有鸭子类型(例如 Java)。还有一些语言具有多态性和鸭子类型(例如 Python)。

于 2012-07-16T10:29:00.353 回答
18

这是 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()
  • 在多态中,我们看到子类 (CatDog) 继承自父类 ( Animal) 并覆盖方法 Talk。
  • 在鸭子类型的情况下,我们不创建子类,而是使用具有相同名称但功能不同的方法创建新类。
于 2013-12-13T06:32:02.983 回答
15

简短的回答:

Duck 类型是实现多态性的一种方式。另一种方法是使用静态类型。

长答案:

这里涉及两个不同的概念,打字和编程技术。

鸭打字是打字的一种。键入意味着传递的对象不是预期的对象时何时抛出错误。Duck typing 是一种在程序运行时抛出错误并且被调用的方法不可用的类型。静态类型带有编译时检查,所以如果类型信息不匹配,它会在编译代码时抛出错误。那就是打字。

多态性是一种编程技术,您可以在其中允许多种类型的对象履行某些职责。您可以通过使用基类型来表示所有子类类型来做到这一点。您可以使用鸭子类型来表示具有所需方法的所有不同类型。您可以使用接口来表示实现该接口的所有类型。

有答案说多态是继承,这是不正确的。虽然您可以使用继承来创建多态行为,通常这就是您所做的,但这不是多态的意义所在。

一方面,您不需要继承来具有如上所述的多态性。

其次,术语“多态性”在依赖于抽象的客户端代码的上下文中更有意义,而不是实现代码。仅仅因为你有一个超类和一些从它继承并覆盖一些方法的其他类并不意味着它是多态性,要创建多态性,你必须以多态方式编写客户端代码来使用这些类。

于 2018-08-20T02:44:25.173 回答
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 
于 2013-05-03T10:22:17.343 回答