8.3 多态与鸭子类型
多态(polymorphism)是指同一个调用,在不同对象上可以表现出不同的行为。Python 没有像 Java 那样必须提前声明变量类型的多态写法;Python 更常见的是鸭子类型(duck typing):如果一个对象拥有调用方需要的方法,就可以被当作合适的对象使用。
同一个方法名,不同实现
下面两个类没有共同父类,但它们都提供了 get_name() 和 get_salary()。调用方只关心“能不能调用这些方法”,不一定关心对象到底属于哪个类。
正在加载交互实验...
python
class FullTimeEmployee:
def __init__(self, name, basic_salary, bonus):
self.__name = name
self.__basic_salary = basic_salary
self.__bonus = bonus
def get_name(self):
return self.__name
def get_salary(self):
return self.__basic_salary + self.__bonus
class PartTimeEmployee:
def __init__(self, name, hourly_wage, hours):
self.__name = name
self.__hourly_wage = hourly_wage
self.__hours = hours
def get_name(self):
return self.__name
def get_salary(self):
return self.__hourly_wage * self.__hours正在加载概念检查...
遍历不同对象
多态让我们可以把不同对象放进同一个列表,并用同一个方法调用处理它们。
python
employees = [
FullTimeEmployee("Alice", 5783, 173),
PartTimeEmployee("Bob", 150, 15)
]
for employee in employees:
print("%s:%d元" % (employee.get_name(), employee.get_salary()))运行结果:
text
Alice:5956元
Bob:2250元循环里只写了 employee.get_salary(),但 Python 会根据对象真实拥有的方法执行对应逻辑。
正在加载概念检查...
什么时候不要强行使用继承
如果两个类只是“刚好都能做某件事”,但并不是同一种事物,就不一定要强行设计父类。Python 里常见的思路是:让不同对象提供同名方法,然后让调用方使用这组共同方法。
例如 Report、Invoice、GradeSheet 都可以提供 export() 方法。导出函数只需要调用 item.export(),不必知道每个对象内部如何生成内容。
python
def export_all(items):
for item in items:
print(item.export())这种写法的好处是扩展性强。以后新增一个类,只要它也有 export(),就可以放进 export_all()。
注意
鸭子类型的直觉是:“如果它走起来像鸭子、叫起来像鸭子,就可以先按鸭子使用。”在代码里,这句话可以理解为:如果对象拥有需要的方法,就可以参与这段调用。
正在加载概念检查...
正在加载本节练习...