码迷,mamicode.com
首页 > 编程语言 > 详细

Python之面向对象(四)类的约束与super()深入了解

时间:2019-08-26 22:53:48      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:基础   提取   模块   info   port   功能   算法   rac   import   

6.6 类的约束

  1. 首先,你要清楚,约束是对类的约束,什么叫抽象类?从小到大的过程叫做抽象

  2. 接口类:(在抽象类的基础上)在python中,默认是没有接口类的,接口类不能被实例化(如果实例化会报错),接口类中的方法不能被实现

    • 例子:

    • #正常调用
      class Applepay:
          def pay(self,money):
             print('apple pay 支付了%s'%money)
      class Alipay:
          def pay(self,money):
              print('支付宝 支付了%s'%money)
      def payment(pay_obj,money):#实例化另外一种调用,这个方法让实例化的时候按照pyment调用就像下面的payment(apple1,200)
          pay_obj.pay(money)
      apple1=Applepay()
      Payment(apple1,200)
    • 有时候写的时候会把方法写错,自己定义一个主动报错;接口初成:手动报异常:NotImplementedError来解决开发中遇到的问题

    • 例子:

    • class Payment:
          def pay(self):
              raise NotImplementedError#主动让程序报错
      class Wechatpay(Payment):#微信支付
         def pay(self,money):
              print('微信支付了%s元'%money)
      class QQchatpay(Payment):#QQ支付
          def fuqian(self,money):
              print('QQ支付了%s元')
      p=Wechatpay()
      p.pay(200)#不报错
      q=QQchatpay()#不报错
      q.pay()#报错,查询子类没有该方法,则查找父类,执行父类的方法,然后报错
    • 借用abc模块来实现接口;接口类(就是为了提供标准,约束后面的子类)

    • 例子:

    • # 3.借用abc模块来实现接口
      #接口类(就是为了提供标准,约束后面的子类)
      from abc import ABCMeta,abstractmethod
      class Payment(metaclass=ABCMeta):
          @abstractmethod
          def pay(self,money):
              pass
      
      class Wechatpay(Payment):
          def fuqian(self,money):
              '''实现了pay的功能,但是方法名字不一样'''
              print('微信支付了%s元'%money)
      
      class Alipay:
          def pay(self,money):
              print('支付宝  支付了%s' %money)
      
      # p = Wechatpay() #报错了(因为上面定义了一个接口类,接口类里面
      # 定义了一个pay方法,而在下面的Wechatpay方法里没有pay方法,不能
      # 调用,在接口类里面约束一下,接口类里的pay方法里面不能写其他,直接pass)
      a = Alipay()
      a.pay(200)
      p = Payment() #接口类不能被实例化
      
      #借用abc模块来实现接口
    • 为何要使用接口:接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

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

      归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

    • 继承的第二种含义非常重要,它又叫做接口继承

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

    • 抽象类:在python中,默认是有的,父类的方法,子类必须实现,抽象类(父类)的方法可以被实现

    • 总结:约束. 其实就是?类对?类进?约束. ?类必须要写xxx?法. 在python中约束的?式和?法有两种:

      1. 使?抽象类和抽象?法, 由于该?案来源是java和c#. 所以使?频率还是很少的
      2. 使??为抛出异常的?案. 并且尽量抛出的是NotImplementError. 这样比较专业, ?且错误比较明确.(推荐)

6.6 super()深入了解

  1. class A:
        def f1(self):
            print('in A f1')
    
        def f2(self):
            print('in A f2')
    
    
    class Foo(A):
        def f1(self):
            super().f2()
            print('in A Foo')
    
    
    obj = Foo()#实例化对象obj 将obj对象地址赋值给object init方法中self中
    obj.f1()#调用子类中的f1方法 遇到super 执行父类中的f2方法 执行完之后继续执行子类f1方法
    #结果为:'in A f2' 'in A Foo'
  2. class A:
        def f1(self):
            print('in A')
    
    class Foo(A):
        def f1(self):
            super(Foo,self).f1()#2 按照mro算法 执行bar类
            print('in Foo')#4 输出
    
    class Bar(A):
        def f1(self):
            print('in Bar')#3输出
    
    class Info(Foo,Bar):
        def f1(self):
            super(Info,self).f1()#1 执行父类 Foo
            print('in Info f1')#5输出
    
    obj = Info()#实例化对象obj,基于Info创建一个对象内存地址赋值给obj
    obj.f1()#执行f1方法 针对多继承 继承顺序采用 mro(c3)算法,先执行Foo
    print(Info.mro)# [<class '__main__.Info'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <class '__main__.A'>, <class 'object'>]
    #结果为:'in Bar''in Foo''in Info f1'
  3. class A:
        def f1(self):
            print('in A')
    
    class Foo(A):
        def f1(self):
            super().f1()
            print('in Foo')
    
    class Bar(A):
        def f1(self):#3
            print('in Bar')#4 输出
    
    class Info(Foo,Bar):
        def f1(self):#1
            super(Foo,self).f1()#2 多继承按照c3算法 Foo下一个是bar 执行bar类
            print('in Info f1')#5 输出
    
    obj = Info()#对象实例化,obj对象地址赋值给object类中init 方法中self参数
    obj.f1()#执行f1函数 现在子类查找(Info)
    #结果为 'in Bar' 'in Info f1'

Python之面向对象(四)类的约束与super()深入了解

标签:基础   提取   模块   info   port   功能   算法   rac   import   

原文地址:https://www.cnblogs.com/zhangdadayou/p/11415357.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!