• python之面向对象封装,多态


    面向对象之封装,多态

    1. 封装

      • 定义:将内容封装在某个地方,以后再去调用被封装在某处的内容

      • 第一步:将内容封装到某处

        class A:
            def __init__(self,name,age):	# 称为构造方法,根据类创建对象时自动执行
                self.name = name
                self.age = age
        obj1 = A('铁憨憨',18) # 将铁憨憨和18分别封装到obj1及self的name和age属性中
        obj2 = A('皮皮寒',16) # 将皮皮寒和16分别封装到obj1及self的name和age属性中
        
      • 第二步:从某处调用被封装的内容

        • 通过对象直接调用

          class A:
              def __init__(self,name,age):
                  self.name = name
                  self.age = age
          obj1 = A('铁憨憨',18)
          obj2 = A('皮皮寒',16)
          print(obj1.name)
          print(obj2.age)
          
        • 通过self间接调用

          class A:
              def __init__(self,name,age):
                  self.name = name
                  self.age = age
              def func(self):
                  print(self.name)
          obj1 = A('铁憨憨',18)
          obj2 = A('皮皮寒',16)
          obj1.func()
          
    2. 多态

      • 定义:同一个对象多种形态,python默认支持多态

        在java或者c#定义变量或者给函数传值必须定义数据类型,否则就报错。

        类似于python这种弱定义类语言,a可以是任意形态(str,int,object等等)。

      • 鸭子类型

        你看起来像鸭子,那么你就是鸭子。如下代码:

        class A:
            def f1(self):
                print('in A f1')
            def f2(self):
                print('in A f2')
        class B:
            def f1(self):
                print('in A f1')
            def f2(self):
                print('in A f2')
                
        obj = A()
        obj.f1()
        obj.f2()
        
        obj2 = B()
        obj2.f1()
        obj2.f2()
        # A 和 B两个类完全没有耦合性,但是在某种意义上他们却统一了一个标准。
        # 对相同的功能设定了相同的名字,这样方便开发,这两个方法就可以互成为鸭子类型。
        
        # 这样的例子比比皆是:str  tuple list 都有 index方法,这就是统一了规范。
        # str bytes 等等 这就是互称为鸭子类型。
        
    3. super

      super是严格按照类的继承顺序执行的。

      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')
      
      class Info(Foo,Bar):
          def f1(self):
              super().f1()
              print('in Info f1')
      
      obj = Info()
      obj.f1()
      
      '''
      in Bar
      in Foo
      in Info f1
      '''
      print(Info.mro())  # [<class '__main__.Info'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <class '__main__.A'>, <class 'object'>]
      
      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')
      
      class Info(Foo,Bar):
          def f1(self):
              super(Foo,self).f1()
              print('in Info f1')
      
      obj = Info()
      obj.f1()
      # in Bar
      # in Info f1
      
    4. 类的约束

      在某些的情况下(在一些重要的逻辑,与用户数据相关等核心部分),我们要建立一种约束,避免发生此类错误.

      • 在父类建立一种约束

        提取父类,然后在父类中定义好方法,在这个⽅法中什么都不用干,就抛⼀个异常就可以了,这样所有的子类都必须重写这个方法,否则,访问的时候就会报错。

        class Payment:
            """
            此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。
            """
            def pay(self,money):
                raise Exception('子类必须定义此方法')
        class Alipay(Payment):
            def pay(self,money):
                print(f'利用支付宝支付了{money}')
        class QQpay(Payment):
            def pay(self,money):
                print(f'利用qq支付了{money}')
        class Wechatpay(Payment):
            def fuqian(self,money):
                print(f'利用微信支付了{money}')
        
        def pay(obj,money):
            obj.pay(money)
        
        obj3 = Wechatpay()
        pay(obj3,100)	# 由于Wechatpay中没有pay方法,会执行Payment中的pay,会弹出错误
        
      • 模拟抽象类(制定一种规范)的概念,建立一种概念

        使用元类来描述父类,在元类中给出一个抽象方法,这样子类就不得不给出抽象方法的具体实现,也可以起到约束效果

        from abc import ABCMeta,abstractmethod
        class Payment(metaclass=ABCMeta):	# # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
            @abstractmethod
            def pay(self,money):	# 抽象方法
                pass
        class Alipay(Payment):
            def pay(self,money):
                print(f'利用支付宝支付了{money}')
        class QQpay(Payment):
            def pay(self,money):
                print(f'利用qq支付了{money}')
        class Wechatpay(Payment):
            def fuqian(self,money):
                print(f'利用微信支付了{money}')
        
        def pay(obj,money):
            obj.pay(money)
        
        obj3 = Wechatpay()	# 在实例化时@abstractmethod会判断obj3中有没有pay方法,如果没有就会报错
        pay(obj3,100)
        
      • 总结:约束就是父类对子类进行约束,子类必须要写xxx方法。

        1. 使用抽象类和抽象方法,由于改方案来源是java和c#,所以使用频率很少
        2. 使用认为抛出异常的方案,并且尽量抛出的是NotlmplementError,这样比较专业,而且错误比较明确。
  • 相关阅读:
    安信天行全方位信息安全态势感知平台建设与运营
    SQL基础总结——20150730
    中兴推“小兴看看”,诠释智能家电的真谛
    Java 线程第三版 第九章 Thread调度 读书笔记
    3930: [CQOI2015]选数|递推|数论
    S​D​I​与​A​S​I 接口具体解释介绍
    通过双重for循环来找到JSON中不反复的数据
    蓝桥杯 2016/3/17 測试 前6题题解...
    [疯狂Java]JDBC:事务管理、中间点、批量更新
    Linux下搭建Memcached缓存系统
  • 原文地址:https://www.cnblogs.com/yaoqi17/p/11164531.html
Copyright © 2020-2023  润新知