VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > 简明python教程 >
  • python基础(24):面向对象三大特性一(继承)(4)

'''
  • def pay(self,money):
  • print('支付宝支付了%s元'%money)
  •  
  • class Applepay:
  • '''
  • apple pay支付
  • '''
  • def pay(self,money):
  • print('apple pay支付了%s元'%money)
  •  
  • class Wechatpay:
  • def fuqian(self,money):
  • '''
  • 实现了pay的功能,但是名字不一样
  • '''
  • print('微信支付了%s元'%money)
  •  
  • def pay(payment,money):
  • '''
  • 支付函数,总体负责支付
  • 对应支付的对象和要支付的金额
  • '''
  • payment.pay(money)
  •  
  • p = Wechatpay()
  • pay(p,200) #执行会报错
  • 接口初成:手动报异常:NotImplementedError来解决开发中遇到的问题。

    
    
    1. class Payment:
    2. def pay(self):
    3. raise NotImplementedError
    4.  
    5. class Wechatpay(Payment):
    6. def fuqian(self,money):
    7. print('微信支付了%s元'%money)
    8.  
    9. p = Wechatpay() #这里不报错
    10. pay(p,200) #这里报错了

    借用abc模块来实现接口。

    
    
    1. from abc import ABCMeta,abstractmethod
    2.  
    3. class Payment(metaclass=ABCMeta):
    4. @abstractmethod
    5. def pay(self,money):
    6. pass
    7.  
    8. class Wechatpay(Payment):
    9. def fuqian(self,money):
    10. print('微信支付了%s元'%money)
    11.  
    12. p = Wechatpay() #不调就报错了

    实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

    继承的第二种含义非常重要。它又叫“接口继承”。 接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

    归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。

    依赖倒置原则:

    高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。

    为何要用接口:

    在python中根本就没有一个叫做interface的关键字,上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,如果非要去模仿接口的概念,可以借助第三方模块。

    接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

    然后让子类去实现接口中的函数。

    这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

    归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

    比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。

    再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样。

    1.5.2 抽象类

    什么是抽象类?

    与java一样,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. pass
    10.  
    11. @abc.abstractmethod #定义抽象方法,无需实现功能
    12. def write(self):
    13. '子类必须定义写功能'
    14. pass
    15.  
    16. # class Txt(All_file):
    17. # pass
    18. #
    19. # t1=Txt() #报错,子类没有定义抽象方法
    20.  
    21. class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    22. def read(self):
    23. print('文本数据的读取方法')
    24.  
    25. def write(self):
    26. print('文本数据的读取方法')
    27.  
    28. class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    29. def read(self):
    30. print('硬盘数据的读取方法')
    31.  
    32. def write(self):
    33. print('硬盘数据的读取方法')
    34.  
    35. class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    36. def read(self):
    37. print('进程数据的读取方法')
    38.  
    39. def write(self):
    40. print('进程数据的读取方法')
    41.  
    42. wenbenwenjian=Txt()
    43.  
    44. yingpanwenjian=Sata()
    
    相关教程