Python中的鸭子类型
一个有关支付方式的例子
支付方式可以有几种,微信支付,支付宝支付,苹果支付等,这几个不同的支付都统一于支付,像这样几个类都统一于某一个类或者某一个方法,或者说一个类有不同的形态的情况就属于多态;虽然几种支付方式都归一于支付类,执行的方法一样,但是每一个支付方式都有自己的特性,实现的形态也不一样,即为多态性。
1 class Payment: 2 def pay(self, money): 3 pass 4 5 class WeChatPay(Payment): 6 def pay(self,money): 7 print('已经使用微信支付了%s元' % money) 8 9 class Alipay(Payment): 10 def pay(self,money): 11 print('已经使用支付宝支付了%s元' % money) 12 13 # pay_obj 可以是WeChatPay实例,也可以是Alipay实例 14 pay_obj.pay(money)
也可以不用在前面加上一个父类对子类进行约束也可以达到多态的效果
1 class WeChatPay(): 2 def pay(self,money): 3 print('已经使用微信支付了%s元' % money) 4 class Alipay(): 5 def pay(self,money): 6 print('已经使用支付宝支付了%s元' % money) 7 8 # pay_obj 可以是WeChatPay实例,也可以是Alipay实例 9 pay_obj.pay(money)
不过Python也提供了一个装饰器,让我们更好的模拟抽象方法
1 class Payment: 2 @abc.abstractmethod 3 def pay(self, money): 4 pass 5 class WeChatPay(): 6 def pay(self,money): 7 print('已经使用微信支付了%s元' % money) 8 class Alipay(): 9 def pay(self,money): 10 print('已经使用支付宝支付了%s元' % money) 11 12 # pay_obj 可以是WeChatPay实例,也可以是Alipay实例 13 pay_obj.pay(money)
python中我们可以通过继承实现多态
通过严格的继承父类,重写父类的方法实现多态
1 class Person(object): 2 3 def __init__(self, name, work=None): 4 self.name = name 5 self.work = None 6 7 def msg(self): 8 # 重载父类的msg方法 9 print('my name is ' + self.name) 10 11 12 class Teacher(Person): 13 def __init__(self, name, work='teacher'): 14 super().__init__(name, work) 15 16 def msg(self): 17 print('my name is ' + self.name + ', my work is ' + self.work) 18 19 class Coder(Person): 20 def __init__(self, name, work='coder'): 21 super().__init__(name, work) 22 23 def msg(self): 24 print('my name is ' + self.name + ', my work is ' + self.work) 25 26 def show_msg(obj): 27 obj.msg() 28 29 if __name__ == '__main__': 30 laowang = Person('laowang') 31 lw_t = Teacher('lw') 32 lw_c = Coder('wcy') 33 34 # 这些都是通过继承方式,创建的新对象, 35 # 严格有Person的所有属性和方法,所以这种多态很好理解 36 show_msg(laowang) 37 show_msg(lw_t) 38 show_msg(lw_c)
鸭子多态
python独特的实现多态的方式,通过Duck Typing。简而言之,不继承父类Person,但是也拥有Person一样的方法或者属性。即看起来像,就行。
1 # 接着上面的代码接着写 2 class Animal(object): 3 def msg(self): 4 print('animal do not need work') 5 # 严格意义上,Animal并没有继承Person父类 6 # 但是它模仿了Person父类,实现了msg方法,看起来像鸭子而已 7 cat = Animal() 8 9 # 所以由于python的解释性,将其定义为鸭子类型,同样实现了多态 10 show_msg(cat)