多态
一、接口类与抽象类
1、实现接口类和抽象类的语法
from abc import abstractclassmethod, ABCMeta
class 父类(mateclass=ABCMeta): # 抽象类/接口类
@abstractclassmethod
def function(): pass
2、接口类
继承有两种用途:(1)继承基类的方法,并做出自己的改变和扩展;(2)声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
接口类:可以多继承,且最好不实现具体功能
from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta): #抽象类/接口类:子类的规范
@abstractmethod
def payment(self,money):pass
class Applepay():
def payment(self,money):
print('apple 支付了 %d元'%money)
class Alipay():
def payment(self,money):
print('支付宝 支付了 %d元' % money)
class Wechatpay():
def payment(self,money):
print('微信 支付了 %d元' % money)
def pay(pay_obj,money): #归一化设计
pay_obj.payment(money)
apple = Applepay()
ali = Alipay()
wechat = Wechatpay()
pay(wechat,100)
pay(apple,200)
pay(ali,300)
依赖倒置原则: 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
3、抽象类
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化。 如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
抽象类:最好单继承,且可以简单的实现功能
例1:抽象类可以简单的实现功能
from abc import abstractmethod,ABCMeta
class Foo(metaclass=ABCMeta): #抽象类
@abstractmethod
def read(self):
f = open()
f.close()
@abstractmethod
def write(self):
f = open()
f.close()
class File(Foo):
def read(self):
super().read()
def write(self):
super().write()
class Disk(Foo):
def read(self):
super().read()
def write(self):
super().write()
例2:抽象类不实现功能
#一切皆文件
import abc #利用abc模块实现抽象类
class All_file(metaclass=abc.ABCMeta):
all_type='file'
@abc.abstractmethod #定义抽象方法,无需实现功能
def read(self):
'子类必须定义读功能'
pass
@abc.abstractmethod #定义抽象方法,无需实现功能
def write(self):
'子类必须定义写功能'
pass
class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('文本数据的读取方法')
def write(self):
print('文本数据的读取方法')
class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('硬盘数据的读取方法')
def write(self):
print('硬盘数据的读取方法')
class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('进程数据的读取方法')
def write(self):
print('进程数据的读取方法')
wenbenwenjian=Txt()
yingpanwenjian=Sata()
jinchengwenjian=Process()
#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()
二、钻石继承
1、经典类与新式类
父类继承object类,称为新式类,否则称为经典类,python3中只有新式类,而python2中同时存在两种类。
class A(object): #新式类,若不继承object则变成经典类
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B):
def test(self):
print('from D')
class E(C):
def test(self):
print('from E')
class F(D,E):
pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
2、继承顺序
如上例,若F类没有test()方法,则会按照继承的属性向上所继承的类进行寻找,找到位置。但是不同的类(新式或者经典)继承的顺序是不同的。其中新式类和经典类继承的顺序如下:


钻石继承:新式类为广度优先,经典类为深度优先的原则进行继承,其中在新式类中可以用:子类名.__mro__ 查看继承顺序,而经典类中此方法不存在。
三、多态特性
python天生支持多态性。
1、多态
指的同一事物有多种形态,如动物有:人、狗、猪形态
import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
@abc.abstractmethod
def talk(self):
pass
class People(Animal): #动物的形态之一:人
def talk(self):
print('say hello')
class Dog(Animal): #动物的形态之二:狗
def talk(self):
print('say wangwang')
class Pig(Animal): #动物的形态之三:猪
def talk(self):
print('say aoao')
2、多态性
多态性是指在不考虑实例类型的情况下使用实例。
peo=People()
dog=Dog()
pig=Pig()
#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()
#更进一步,我们可以定义一个统一的接口来使用
def func(obj):
obj.talk()


浙公网安备 33010602011771号