3.3 多态是对功能的抽象
多态的含义是,实现同一个功能的方法可以有不同的表现形态。在实际应用中往往会整合性地使用“继承”和“多态”这两大特性。
如果两个方法同名,但参数个数不同,这在Java等语言里是允许的,但在Python语言中不支持,所以多态特性在Python中的表现形式是,方法同名但参数类型不同,或者同一个方法能适用于不同类型的调用场景。
3.3.1 Python中的多态特性
在前文提到过多态特性,下面通过PolyDemo.py范例程序从一些熟悉的程序语句中来归纳一下“多态”的具体表现方式。
1 # !/usr/bin/env python 2 # coding=utf-8 3 print(1+1) # 输出是1 4 print("1"+"1") # 输出是11 5 areaList=["ShangHai","HangZhou"] 6 print(areaList) # print能适用于不同类型的参数 7 print("abc".index("a")) 8 print(["a","b","c"].index("b"))
从第3行和第4行的程序语句,可以看到对于同一种运算符(即同一种功能)加号,当参数(或操作数)不同时,会执行不同的操作。比如参数是数字时,会执行加法操作,如果是字符串时,会执行字符串的连接操作。另外,对于同一个方法print,当参数不同时(参数分别是数字类型和字符串类型),也会执行不同的操作,即输出数字类型和字符串类型的对象。
这就是多态特性的具体表现方式,即同一种功能,比如上面范例程序中的print方法,随着输入参数类型的不同,会有不同的表现形态,即能输出整数类型或字符串类型。
在第7行和第8行中,可以看到index方法会随着调用主体的不同,展现出不同的形态,比如在第7行中,会从字符串里找到单词的索引值,而在第8行中,是从列表里找单词的索引值,这也体现了多态的特性。
3.3.2 多态与继承结合
多态往往会和继承结合使用,即当一个父类的不同子类调用同一个方法时,该方法会有不同的表现形式。在下面的PolyInhertanceDemo.py范例程序中可以看到整合多态和继承这两者的用法。
1 # !/usr/bin/env python 2 # coding=utf-8 3 class Employee(object): 4 def __init__(self,name): 5 self.__name=name 6 def work(self): 7 print(self.__name + " Work.") 8 class Manager(Employee): 9 def __init__(self,name): 10 self.__name=name 11 def check(self): 12 print("Manage check work.") 13 def work(self): 14 print(self.__name + " Work.") 15 self.check() 16 class HR(Employee): 17 def __init__(self,name): 18 self.__name=name 19 def calSalary(self): 20 print("HR calculate Salary.") 21 def work(self): 22 print(self.__name + " Work.") 23 self.calSalary() 24 # 调用类 25 manager=Manager("Peter") 26 manager.work() 27 hr=HR("Mike") 28 hr.work()
第8行的Manager类和第16行的HR类都是Employee的子类,在其中都有work方法,但在不同的子类里,work方法有不同的功能,即表现形式不同。
第25行和第27行的程序语句分别创建了Manager和HR这两个类的对象,虽然它们都是Employee的子类,但在第26行和第28行调用其中的work方法时,能根据调用主体的不同,分别调用对应类的work方法,下面的输出语句即可验证出这一效果。
Peter Work. Manage check work. Mike Work. HR calculate Salary.