zoukankan      html  css  js  c++  java
  • 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,这样比较专业,而且错误比较明确。
  • 相关阅读:
    如何通过命令行窗口查看sqlite数据库文件
    eclipse自动补全的设置
    文本装饰
    注释和特殊符号
    文本装饰
    网页背景
    通过ArcGIS Server admin 查看和删除已注册的 Web Adaptor
    通过 ArcGIS Server Manager 查看已安装的 Web Adaptor
    通过 ArcGIS Server Manager 验证 DataStore
    Windows上安装ArcGIS Enterprise——以 Windows Server 2012 R2上安装 ArcGIS 10.8为例
  • 原文地址:https://www.cnblogs.com/yaoqi17/p/11164531.html
Copyright © 2011-2022 走看看