Python进阶-XVII 非python的接口类、多态、python自己的封装
1、python模拟java中的接口类
python中是没有接口类的概念的,因为它支持多继承,但是java不能,所以就提出一个接口类的概念
java : 面向对象编程
设计模式 —— 接口
接口类 : python原生不支持
抽象类 : python原生支持的
例子:有三种特性,能走,能飞,能游泳,如下三个类,就有了类似java中接口类的作用了。
1 class Fly:pass 2 class Walk:pass 3 4 # 用多继承,可以表明一个动物的多个本领 5 class Swan(Fly, Walk):pass 6 class Dog(Walk):pass 7 8 # 上面只是模拟,真实情况下不是这样使用,而是使用语法糖@abstarctmethod来实现。规范代码用! 9 from abc import ABCMeta,abstractmethod 10 class Swim(metaclass=ABCMeta): 11 @abstractmethod 12 def swim(self):pass 13 14 class Fish(Fly): 15 def swim(self): # 如果不实现该方法,会报错:TypeError: Can't instantiate abstract class Fish with abstract methods swim 16 print('eagle fling') 17 18 eagle = Fish()
继续举例:
1 class Wechat(Payment): 2 def pay(self,money): 3 print('已经用微信支付了%s元'%money) 4 5 class Alipay(Payment): 6 def pay(self,money): 7 print('已经用支付宝支付了%s元' % money) 8 9 class Applepay(Payment): 10 def pay(self,money): 11 print('已经用applepay支付了%s元' % money) 12 13 def pay(pay_obj,money): # 统一支付入口 14 pay_obj.pay(money) 15 16 # wechat = Wechat() 17 # ali = Alipay() 18 app = Applepay() 19 # wechat.pay(100) 20 # ali.pay(200) 21 #p = Payment() #TypeError: Can't instantiate abstract class Payment with abstract methods pay
接口类就是多继承
1 # tiger 走路 游泳 2 # swan 走路 游泳 飞 3 # oldying 走路 飞 4 from abc import abstractmethod,ABCMeta 5 class Swim_Animal(metaclass=ABCMeta): 6 @abstractmethod 7 def swim(self):pass 8 9 class Walk_Animal(metaclass=ABCMeta): 10 @abstractmethod 11 def walk(self):pass 12 13 class Fly_Animal(metaclass=ABCMeta): 14 @abstractmethod 15 def fly(self):pass 16 17 class Tiger(Walk_Animal,Swim_Animal): 18 def walk(self): 19 pass 20 def swim(self): 21 pass 22 class OldYing(Fly_Animal,Walk_Animal):pass 23 class Swan(Swim_Animal,Walk_Animal,Fly_Animal):pass 24 25 # 接口类 刚好满足接口隔离原则 面向对象开发的思想 规范
2、强类型语言中的多态
什么是多态
python 动态强类型的语言
鸭子类型
list tuple
不崇尚根据继承所得来的相似
我只是自己实现我自己的代码就可以了。
如果两个类刚好相似,并不产生父类的子类的兄弟关系,而是鸭子类型
list tuple 这种相似,是自己写代码的时候约束的,而不是通过父类约束的
优点 : 松耦合 每个相似的类之间都没有影响
缺点 : 太随意了,只能靠自觉
1 class Payment:pass 2 3 class Alipay(): 4 def pay(self,money): 5 print('已经用支付宝支付了%s元' % money) 6 7 class Applepay(): 8 def pay(self,money): 9 print('已经用applepay支付了%s元' % money) 10 11 def pay(pay_obj,money): # 统一支付入口 归一化设计 12 pay_obj.pay(money) 13 14 pay()
因为强类型语言,传参时必须指定参数类型!
而python不必如此,天生支持多态,因为它是动态的强类型语言,在传参时没有要求指定类型!
多态 python 天生支持多态
1 class List(): 2 def __len__(self):pass 3 class Tuple(): 4 def __len__(self):pass 5 6 def len(obj): 7 return obj.__len__() 8 9 l = Tuple() 10 len(l) 11 12 # 强类型语言 多态 13 # python 语言 鸭子类型 14 15 16 # 接口类和抽象类 在python当中的应用点并不是非常必要
3、抽象类
抽象类 : 规范
一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中
抽象类还是接口类 : 面向对象的开发规范 所有的接口类和抽象类都不能实例化
java :
java里的所有类的继承都是单继承,所以抽象类完美的解决了单继承需求中的规范问题
但对于多继承的需求,由于java本身语法的不支持,所以创建了接口Interface这个概念来解决多继承的规范问题
python
python中没有接口类 :
python中自带多继承 所以我们直接用class来实现了接口类
python中支持抽象类 : 一般情况下 单继承 不能实例化
且可以实现python代码
1 #一切皆文件 2 import abc #利用abc模块实现抽象类 3 4 class All_file(metaclass=abc.ABCMeta): 5 all_type='file' 6 @abc.abstractmethod #定义抽象方法,无需实现功能 7 def read(self): 8 '子类必须定义读功能' 9 with open('filaname') as f: 10 pass 11 12 @abc.abstractmethod #定义抽象方法,无需实现功能 13 def write(self): 14 '子类必须定义写功能' 15 pass 16 17 class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法 18 def read(self): 19 print('文本数据的读取方法') 20 def write(self): 21 print('文本数据的读取方法') 22 23 class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法 24 def read(self): 25 print('硬盘数据的读取方法') 26 27 def write(self): 28 print('硬盘数据的读取方法') 29 30 class Process(All_file): #子类继承抽象类,但是必须定义read和write方法 31 def read(self): 32 print('进程数据的读取方法') 33 34 def write(self): 35 print('进程数据的读取方法') 36 37 wenbenwenjian=Txt() 38 39 yingpanwenjian=Sata() 40 41 jinchengwenjian=Process() 42 43 #这样大家都是被归一化了,也就是一切皆文件的思想 44 wenbenwenjian.read() 45 yingpanwenjian.write() 46 jinchengwenjian.read() 47 48 print(wenbenwenjian.all_type) 49 print(yingpanwenjian.all_type) 50 print(jinchengwenjian.all_type)
4、python自己的封装
广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种
只让自己的对象能调用自己类中的方法
狭义上的封装 —— 面向对象的三大特性之一
属性 和 方法都藏起来 不让你看见
1 class A: 2 name = 'jack' 3 def get(self): 4 return A.name 5 6 print(A.name) 7 a = A() 8 print(a.get()) 9 10 class B: 11 __name = 'tom' # 私有化的属性 12 def __get(self): # 私有化的方法,外边不能访问 13 return A.name 14 15 def get(self): # 共有方法,调用私有方法 16 self.__get() 17 18 #print(B.__name) # AttributeError: type object 'B' has no attribute '__name' 19 b = B() 20 #print(b.__get()) # AttributeError: 'B' object has no attribute '__get' 21 b.get() 22 23 class Person: 24 __key = 123 # 私有静态属性 25 def __init__(self,name,passwd): 26 self.name = name 27 self.__passwd = passwd # 私有属性 28 29 def __get_pwd(self): # 私有方法 30 return self.__passwd #只要在类的内部使用私有属性,就会自动的带上_类名 31 32 def login(self): # 正常的方法调用私有的方法 33 self.__get_pwd() 34 35 alex = Person('alex','alex3714') 36 print(alex._Person__passwd) # _类名__属性名 37 #print(alex.get_pwd())
所有的私有 都是在变量的左边加上双下划綫
对象的私有属性
类中的私有方法
类中的静态私有属性
所有的私有的 都不能在类的外部使用

浙公网安备 33010602011771号