静态类型语言(如 Java)实现多态:
abstract class Animal {
void say() {
System.out.println("I am an animal.");
}
}
class Cat extends Animal {
void say() {
System.out.println("I am a cat.");
}
}
class Dog extends Animal {
void say() {
System.out.println("I am a dog.");
}
}
ArrayList<Animal> animals = new ArrayList<>();
animals.add(new Cat());
animals.add(new Cat());
animals.add(new Cat());
animals.add(new Dog());
animals.add(new Dog());
animals.add(new Dog());
for (Animal anm: animals) {
anm.say();
}
/*
I am a cat.
I am a cat.
I am a cat.
I am a dog.
I am a dog.
I am a dog.
*/
Python 也可以这样实现:
class Animal:
def say(self):
print('I am an animal.')
class Cat(Animal):
def say(self):
print('I am a cat.')
class Dog(Animal):
def say(self):
print('I am a dog.')
animals = []
animals.extend([Cat() for _ in range(3)])
animals.extend([Dog() for _ in range(3)])
for anm in animals:
anm.say()
但实际上 Python 根本不需要这样实现,Python 只需要保证 Cat
和 Dog
类中包含 say
方法即可。
class Cat:
def say(self):
print('I am a cat.')
class Dog:
def say(self):
print('I am a dog.')
animals = []
animals.extend([Cat() for _ in range(3)])
animals.extend([Dog() for _ in range(3)])
for anm in animals:
anm.say()
鸭子类型(英语:duck typing)在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由 当前方法和属性的集合 决定。
在鸭子类型中,关注点在于对象的行为,能做什么,而不是关注对象所属的类型。
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
Python:
def animal_say(anm):
anm.say()
animal_say(Cat())
animal_say(Dog())
class Xxx:
def say():
print('I am a xxx.')
animal_say(Xxx())
Java:
void animal_say(Animal anm) {
anm.say();
}
animal_say(new Cat());
animal_say(new Dog());
class Xxx extends Animal {
void say() {
System.out.println('I am a xxx.');
}
}
animal_say(new Xxx());
在常规类型中,我们能否在一个特定场景中使用某个对象取决于这个对象的类型,而在鸭子类型中,则取决于这个对象是否具有某种属性或者方法,即只要具备特定的属性或方法,就可以使用。
鸭子类型在不使用继承的情况下使用了多态。
Python 中广泛使用到鸭子类型,比如:
一个类,只要实现了 __iter__()
或 __getitem__()
方法,那么它实例化的对象就是个可迭代对象。
class Company:
def __init__(self, employee_list):
self.employees = employee_list
def __getitem__(self, index):
return self.employees[index]
obj = Company(['xf', 'rz', 'hyf', 'zll', 'lns'])
lst = []
lst.extend(obj)
鸭子类型和魔法函数是 Python 面向对象编程的基础,是 Python 从一开始就设计好的。
因为 Python 有鸭子类型的概念,所以我们无需用继承的方式实现多态,Python 从语言层面就是支持多态的。