day 12 接口##
一,抽象类和接口类
1 什么时抽象类:可以事项具体的某个功能,并且不知此多继承的这个父类就叫做抽象类
2 什么时接口类:不是想具体的方法的并且推荐多继承的这个父类就叫做接口类
抽象类和接口类都是为了定义子类的规范
3 什么叫做归一化设计:创建一个函数来调用类里面的属性或方法,不需要(对象.方法())来调用,这种设计思想就叫做归一化设计。前提条件是几个类都实现相同的功能
4 abc模块,用于接口类和抽象类中一个模块
ABC是Abstract Base Class的缩写。
abc.ABCMeta:由于生成抽象类和接口类的抽象方法和抽象属性,由他生成的类可以直接被继承。
abc.abstractmethod:给父类的方法加上一个装饰器。
接口类;
1 # import abc 2 # class Payment(metaclass=abc.ABCMeta): 3 # @abc.abstractmethod 4 # def payment(self哦,monry):pass 5 # class Wei(Payment): 6 # def payment(self,monry): 7 # print('微信支付%s元'%monry) 8 # class Zhi(Payment): 9 # def fuqian(self,monry): 10 # print('支付宝支付%s元'%monry) 11 # def payment(suixiang,monry): 12 # suixiang.payment(monry) 13 # d1=Wei() 14 # payment(d1,100) 15 # 16 # d2=Zhi() #报错 17 # payment(d2,200) #报错
如果在子类中没有和接口类相同的方法,只要创建该子类对象就会报错
抽象类:
# import abc # class Payment(metaclass=abc.ABCMeta): # @abc.abstractmethod # def payment(self,money): # print('支付了%s元'%(money)) # class Wei(Payment): # def payment(self,monry): # super().payment(monry) # class Zhi(Payment): # def pay_ment(self,money): # pass # def payment(self,money): # self.payment(money) # w1=Wei() # payment(w1,100) # # z1=Zhi() # payment(z1,200)
多继承一般情况下不用,但是可以在接口类的情况下使用
# from abc import ABCMeta,abstractmethod # class Fly_animal(metaclass=ABCMeta): # @abstractmethod # def fly(self):pass # class Walk_animal(metaclass=ABCMeta): # @abstractmethod # def walk(self):pass # class Swim_animal(metaclass=ABCMeta): # @abstractmethod # def swim(self):pass # class Tiger(Walk_animal,Swim_animal): # def walk(self):print('%s is walking'%self) # def swim(self):print('%s is swiming'%self) # class Frog(Walk_animal,Swim_animal): # def walk(self):print('%s is walking'%self) # def swim(self):print('%s is swiming'%self) # class Swan(Fly_animal,Walk_animal,Swim_animal): # def walk(self):print('%s is walking'%self) # def swim(self):print('%s is swiming'%self) # def fly(self):print('%s is flying'%self) # t1=Tiger() # t1.walk() # f1=Frog() # f1.swim() # s1=Swan() # s1.fly()
依赖倒置原则:高层的模块应该不依赖于底层模块;二者都应该依赖于抽象;抽象不应该依赖于细节;细节应该依赖于抽象;
换言之;要针对接口编程,而不是针对实现编程
接口隔离原则:使用多个专门的接口,而不是使用单一的总接口,即客户端应该不依赖于那些不需要的接口
二 新式类和经典类
1 python中分为新式类和经典类
在python2 中定义经典类, class 父类名:
在python2 中定义新式类,class 父类名(object):
object是所有类的基类。
新式类和经典类在继承的顺序上的不同:在新式类中属于官渡优先;在经典类中属于深度优先。
什么叫深度优先:
在经典类中,从左到右每个分支查找到底,在进行下一个分支的查找,如果有共同的父类,在查找的第一个分支,就会查找到这个共同的父类,然后在进行下一个分支的查找,在后面查找是不会在去查找他们共同的父类。
什么叫广度优先:
在新式类中,从左到右每个分支查找完毕到他们的共同父类下的子类后,在去查找下一条分支,直到共同父类下的分组查找完毕过后,最后在查找他们共同的父类。
## mro()可以查看寻找的顺序,经典类中不能使用:
# class A: # def func(self): # print('A') # class B(A): # def func(self): # print('B') # class C(B): # def func(self): # print('C') # class D(A): # def func(self): # print('D') # class E(D): # def func(self): # print('E') # class F(A): # def func(self): # print('F') # class G(F): # def func(self): # print('G') # class H(C,E,G): # def func(self): # print('H') # h=H() # h.func() # print(H.mro())
调用经典类:父类名(子类名,对象).功能或者方法。调用是需要传入两个参数,一个是子类名,一个是对象
调用新式类:父类名().功能或者方法。父类可以不需要传入参数。
在python3 中只有新式类,而没有经典类。
三 多态
什么是多态:一种事物的多种形态叫做多态,这里指的是一个参数的多种形态
python是自带多态的
什么是多态性:在python中一个参数可以使用多种数据类型,就叫做多态性
鸭子类型:在各种数据类型之间他们没有任何的联系,但是他们拥有着一些共同的属性或者功能,这就叫做鸭子类型。