python 面向对象专题(四):封装、多态、鸭子类型、类的约束、super

https://www.cnblogs.com/liubing8/p/11321099.html

1. 封装

  • 把一堆东西(代码,数据)放到一个地方(空间),并且可以使用,比如:函数,类

2. 多态

  • 一个事物可以呈现多种形态 , 例如:水可以支持固态、液态、气态

  • Python默认支持多态(Java是强定义语言,Python是弱定义语言)

  • Python一个变量可以支持多种数据

  • 代码示例:

    python:
        a = [1,2,3]
        a = "abc"
    Java:
        int a = 123

3. 鸭子类型

  • Python崇尚鸭子类型(一种编程思路)

  • 看起来像鸭子就是鸭子类型

  • 将相似的功能,起同一名字,一种开发思路

  • 虽然A,B两个类没有关系,但是统一两个类中相似方法的方法名,在某种意义上是统一了一个标准

  • 优点:方便记忆,例如:str tuple list 都有 index方法,这就是统一了规范

  • 代码示例:

    class A:
        def login(self):
            print('登录')
        def register(self):
            print('注册')
        def func1(self):
            pass
        def func2(self):
            pass
    
    class B:
        def login(self):
            print('登录')
        def register(self):
            print('注册')
        def func3(self):
            pass
    
    # A B互为鸭子.

4. 类的约束

  • python中对类的约束有两种:在父类主动抛出错误;接口类/抽象类

  • Python语言惯于使用的一种约束方式,在父类主动抛出错误

    提取⽗类. 然后在⽗类中定义好⽅法. 在这个⽅法中什么都不⽤⼲. 就抛⼀个异常就可以了. 这样所有的⼦类都必须重写这个⽅法. 否则. 访问的时候就会报错.

    代码示例:

    class Payment:
       """
       此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。
       """
       def pay(self,money):
           raise Exception("你没有实现pay方法")
    
    class QQpay(Payment):
       def pay(self,money):
           print('使用qq支付%s元' % money)
    
    class Alipay(Payment):
       def pay(self,money):
           print('使用阿里支付%s元' % money)
    
    class Wechatpay(Payment):
       def fuqian(self,money):
           print('使用微信支付%s元' % money)
    
    def pay(obj,money):
       obj.pay(money)
    
    a = Alipay()
    b = QQpay()
    c = Wechatpay()
    pay(a,100)
    pay(b,200)
    pay(c,300)
  • 接口类/抽象类(借鉴于Java语言,定义抽象类的概念,做到真正的强制约束)

    使⽤元类来描述⽗类. 在元类中给出⼀个抽象⽅法. 这样⼦类就不得不给出抽象⽅法的具体实现. 也可以起到约束的效果

    代码示例:

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):    # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
        @abstractmethod
        def pay(self):pass  # 抽象方法
    
    class Alipay(Payment):
        def pay(self,money):
            print('使用支付宝支付了%s元'%money)
    
    class QQpay(Payment):
        def pay(self,money):
            print('使用qq支付了%s元'%money)
    
    class Wechatpay(Payment):
        # def pay(self,money):
        #     print('使用微信支付了%s元'%money)
        def recharge(self):pass
    
    def pay(a,money):
        a.pay(money)
    
    a = Alipay()
    a.pay(100)
    pay(a,100)    # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
    q = QQpay()
    q.pay(100)
    pay(q,100)
    w = Wechatpay()
    pay(w,100)   
    
    总结:
     - 抽象类在实例化的时候,没有抽象类里边的方法就用报错
     - 主动抛错,只有在用到类里边的方法才会报错
    
    
    # 抽象类和接口类做的事情 :建立规范
    # 制定一个类的metaclass是ABCMeta,
    # 那么这个类就变成了一个抽象类(接口类)
    # 这个类的主要功能就是建立一个规范

5. super的深度剖析

  • super(类名,self)
    类名:要跳过的类,self指的是严格按照self对象从属类的mro的执行顺序去执行

  • 代码示例:

    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):
            print('in Bar')  # 1
    class Info(Foo,Bar):
        def f1(self):
            super(Foo,self).f1()
            print('in Info f1')  # 2
            
    obj = Info()
    obj.f1()
    
    #mro执行顺序:[Info Foo Bar A]
    # 结果:
    in Bar
    in Info f1
原文地址:https://www.cnblogs.com/qiu-hua/p/12858635.html