8.3 Polymorphism and Duck Typing
Polymorphism means the same call can behave differently on different objects. Python does not require Java-style variable type declarations for this idea. A common Python style is duck typing: if an object provides the methods the caller needs, it can be used.
Same Method Name, Different Implementations
The two classes below do not share a parent class, but both provide get_name() and get_salary(). Caller code cares about whether those methods exist, not necessarily about the exact class.
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.__hoursLooping Through Different Objects
Polymorphism lets us put different objects in the same list and handle them with the same method call.
employees = [
FullTimeEmployee("Alice", 5783, 173),
PartTimeEmployee("Bob", 150, 15)
]
for employee in employees:
print("%s: $%d" % (employee.get_name(), employee.get_salary()))Output:
Alice: $5956
Bob: $2250The loop only writes employee.get_salary(), but Python runs the behavior provided by each object's real class.
When Not to Force Inheritance
If two classes merely can do the same action but are not really the same kind of thing, you do not always need to force a parent class. A common Python approach is to let different objects provide the same method name and let caller code use that shared method.
For example, Report, Invoice, and GradeSheet can all provide an export() method. The exporting function only needs to call item.export().
def export_all(items):
for item in items:
print(item.export())This is easy to extend. A new class can join export_all() as long as it also provides export().