zoukankan      html  css  js  c++  java
  • python之面向对象性封装,多态,以及鸭子类型

    默认类型

    class A:
    
        class_name = 'python23期'
    
        def __init__(self, name, age):
    
            self.name = name
            self.age =age
    
    a1 = A('李业', 21) # 实例化一个a1的对象
    print(a1.name)
    
    a2 = A('李东宇', 24) # 实例化一个a2的对象
    print(a2.age)
    

    封装

    把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了⼀个很⽜B的函数. 那这个也可以被称为封装. 在⾯向对象思想中. 是把⼀些看似⽆关紧要的内容组合到⼀起统⼀进⾏存储和使⽤. 这就是封装.

    多态

    一个事务有多种形态 比如水

    什么是多态: 在python中默认支持多态,就是a可以定义多种数据类型,不用规定其所属的数据类型,可以是字符串,列表,元组等任意数据类型

    python中定义变量不用规定变量的类型
    a = 'alex'
    a = [1, 2, 3]
    a = (22, 33)
    
    
    Java
    int a = 12 # a必须是整型
    String b = 'abc'# b必须是一个字符串类型的
    

    鸭子类型

    python中你看起来像鸭子,那么你就是鸭子

    就是相互独立的两个类,本身是没有什么关系的,然后它们内部有共同的名字func,这种就是鸭子

    格式

    class A:
    
        def login(self):
            pass
    
        def register(self):
            pass
    
    
    class B:
    
        def login(self):
            pass
    
        def register(self):
            pass
    # A,B两个类,没有任何关系,独立两个,但是里面的功能相似,所以python一般会将类似于A,B两个类
    # 里面的相似的功能让其命名相同.
    # 1. A,B虽然无关系,但是很默契的制定了一个规范.让你使用起来更方便.
    

    super

    格式

    class A:
        def f1(self):
            print('in A f1')
    
        def f2(self):
            print('in A f2')
    
    
    class Foo(A):
        def f1(self):
            # super().f2()
            super(Foo, self).f2()
            print('in A Foo')
    
    
    obj = Foo()
    obj.f1()
    # 执行结果
    in A f2
    in A Foo
    
    
    class A:
        def f1(self):
            print('in A')
    
    class Foo(A):
        def f1(self):
            super(Foo,self).f1()
            print('in Foo')  # 2
    
    class Bar(A):
        def f1(self):
            print('in Bar')  # 1
    
    class Info(Foo,Bar):
    
        def f1(self):
            super(Info,self).f1()
            print('in Info f1')  # 3
    
    obj = Info()
    print(Info.mro())  # [Info, Foo, Bar, A]
    obj.f1()
    # 执行结果
    [<class '__main__.Info'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <class '__main__.A'>, <class 'object'>]
    in Bar
    in Foo
    in Info f1
    

    super() 严格意义并不是执行父类的方法.

    单继承: super() 肯定是执行父类的方法.

    多继承: super(S,self) 严格按照self从属于的类的mro的执行顺序,执行 S类的下一位.***

    类的约束

    # 版本二 统一接口
    class Wecht:
    
        def pay(self,money):
            print(f'利用微信支付了{money}')
    
    
    class Alipay:
    
        def pay(self, money):
            print(f'利用支付宝支付了{money}')
    
    
    def pay(obj, money): # 定义一个统一化的设计
    obj.pay(money)
    
    obj1 = Wecht()
    obj2 = Alipay()
    
    pay(obj1,200)
    pay(obj2,300)
    
    # 输出结果
    利用微信支付了200
    利用支付宝支付了300
    
    # 版本三 野路子写法
    
    # 版本四 按照之前的代码逻辑进行改变
    
    发现问题:
    以上代码没有约束,原因就是想怎么写就怎么写,都能实现当时的功能(个人理解)
    在上面的情况下(在一些重要的逻辑,与用户数据相关等核心部分),我们要建立一种约束,避免发生此类错误
    
    

    类的约束有两种解决方式

    1. 在父类建立一种约束
    2. 利用抽象类(指定的一种规范)的概念

    第一种解决方式(建议使用方式)

    在父类定义一个pay方法,主动抛出异常,如果子类没有定义pay方法,并且

    再建立一个父类pay的方法,约定俗称定义一种规范,子类要定义pay方法,但是没有强制性,还是可以执行
    	raise 主动报错提醒
    class Payment:
        def pay(self,money):
            raise Exception('必须得定义这个类')
    
    class Wechat(Payment):
    
        def pay(self,money):
            print(f'利用微信支付了{money}')
    
    
    class Alipay(Payment):
    
        def pay(self, money):
            print(f'利用支付宝支付了{money}')
    
    class QQpay(Payment):
    
        def fuqian(self, money):
            print(f'利用QQ支付了{money}')
    
    def pay(obj, money):
        obj.pay(money)
    
    obj1 = Wechat()
    obj2 = Alipay()
    
    pay(obj1,200)
    pay(obj2,300)
    
    obj3 = QQpay()
    pay(obj3,599)
    
    # 输出结果
    Traceback (most recent call last):
      File "/Users/wuqiang/work/PycharmProjects/python23/day24/day24.py", line 50, in <module>
        pay(obj3,599)
      File "/Users/wuqiang/work/PycharmProjects/python23/day24/day24.py", line 41, in pay
        obj.pay(money)
      File "/Users/wuqiang/work/PycharmProjects/python23/day24/day24.py", line 22, in pay
        raise Exception('必须得定义这个类')
    Exception: 必须得定义这个类
    

    第二种解决方式

    利用抽象类概念, 基类如先设置,子类如果没有定义pay方法,在实例化对象的时候就会抛出错误

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self, money):
            pass
    
    class Wecht(Payment):
    
        def pay(self,money):
            print(f'利用微信支付了{money}')
    
    
    class Alipay(Payment):
    
        def pay(self, money):
            print(f'利用支付宝支付了{money}')
    
    class QQpay(Payment):
    
        def fuqian(self, money):
            print(f'利用QQ支付了{money}')
     
    obj3 = QQpay()
    # 输出结果
        obj3 = QQpay()
    TypeError: Can't instantiate abstract class QQpay with abstract methods pay
    
  • 相关阅读:
    Debug相关的一些小技巧
    <Information Storage and Management> 读书笔记 之二
    <<Information Storage and Management>>读书笔记 之三
    LINQ to SQL语句(2)之Select/Distinct【转】
    Asp.Net MVC实践 探索UrlRouting并分析UrlHelper (基于ASP.NET MVC Preview 3) 【转】
    MVC学习之分页 【转】
    在 ASP.NET MVC 项目中使用 WebForm 【转】
    Asp.net Mvc Codeplex Preview 5 第三篇 实现Action参数传递繁杂类型 【转】
    jQuery入门[1]-构造函数 【转】
    LINQ to SQL语句(1)之Where【转】
  • 原文地址:https://www.cnblogs.com/zanao/p/11227551.html
Copyright © 2011-2022 走看看