zoukankan      html  css  js  c++  java
  • Python之面向对象(四)类的约束与super()深入了解

    类的约束

    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'
      
  • 相关阅读:
    第03组 Alpha冲刺(2/4)
    第03组 Alpha冲刺
    第09组 Beta版本演示
    第09组 Beta冲刺(4/4)
    第09组 Beta冲刺(3/4)
    第09组 Beta冲刺(2/4)
    第09组 Beta冲刺(1/4)
    第09组 Alpha事后诸葛亮
    第09组 Alpha冲刺(4/4)
    第09组 Alpha冲刺(3/4)
  • 原文地址:https://www.cnblogs.com/zhangdadayou/p/11415357.html
Copyright © 2011-2022 走看看