定义

“一个走起来像鸭子,游起来像鸭子,叫起来也像鸭子,那么就可认为它是一只鸭子!”

要点

  • 鸭子类型是一种动态类型风格

  • 一个对象有效的语义(方法或属性),不是由继承自特定的类或实现特定的接口,而是由它本身所具有的方法和属性的集合来决定

  • 在一个具体的上下文中(函数),只关心该对象是否具有相应的语义(方法或属性),而不关心其真实类型

  • 属于一种多态,且不需要继承,灵活性更强!

  • 若该对象在鸭子测试中(函数使用该对象的方法或属性),不能通过,则抛出异常(类型错误)

  • 通过良好的文档,清晰的代码,完备的测试,来保证类型类型正常工作

实例

python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")

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()

def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)

game()

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

template <typename T>
struct Caller {
const T callee_;
Caller(const T callee) : callee_(callee) {}
void go() { callee_.call(); }
};

struct Foo {
void call() const { std::cout << "Foo"; }
};

struct Bar {
void call() const { std::cout << "Bar"; }
};

int main() {
Caller<Foo> foo{Foo()};
Caller<Bar> bar{Bar()};
foo.go();
bar.go();
std::cout << std::endl;
return 0;
}

参考

  1. https://en.wikipedia.org/wiki/Duck_test
  2. https://en.wikipedia.org/wiki/Duck_typing
  3. http://nullprogram.com/blog/2014/04/01/

留言