• 接口类和抽象类


    接口类和抽象类(都是一种思想概念)

    一、简单的说明什么是接口类和抽象类

      Java主要是面向对象编程的,比较推崇设计模式,而接口是在设计模式里面的一种思维概念,所以接口类是Java里面原生支持的,而python中原生不支持接口类,但是由于设计模式里面有接口类这个概念,而python也会用到设计模式的思维,所以也会接触到接口类。

    接口类:python原生不支持

    抽象类:python原生支持

    二、在代码里面实现接口类

    定义几种支付方式,并且最后统一支付入口,代码如下:

    class Wechatpay:
        def pay(self,money):
            print('已经使用微信支付了%s元' % money)
    
    class Alipay:
        def pay(self,money):
            print('已经使用支付宝支付了%s元' % money)
    
    # 再定义一个Applepay类
    class Aapplepay:
        def fuqian(self,money):  # 这里不是使用pay函数
            print('已经使用苹果支付了%s元' % money)
    
    def pay(pay_obj,money):
        # 统一支付入口,不管使用哪种方式,主要就是支付就可以了
        pay_obj.pay(money)
    
    wechat = Wechatpay()
    # 实例化
    ali = Alipay()
    # 实例化
    app = Aapplepay()
    # 实例化
    pay(wechat,100)  # 通过微信支付100
    pay(ali,200)  # 通过支付宝支付200
    pay(app,300)  # 这里调用pay函数,但是前面Applepay里面使用的不是pay函数而是fuqian,所以这里结果将会报错

    运行结果:

    C:Userssku1-1PycharmProjectsuntitledvenvScriptspython.exe C:/Users/sku1-1/PycharmProjects/untitled/学习笔记/接口类和抽象类.py
    已经使用微信支付了100元
    已经使用支付宝支付了200元
    Traceback (most recent call last):
      File "<encoding error>", line 26, in <module>
      File "<encoding error>", line 16, in pay
    AttributeError: 'Aapplepay' object has no attribute 'pay'

      从上面的运行结果可以知道,定义的第三种支付方式,通过统一支付入口后将无法支付,结果就会报错,改变一下报错的方式,如下代码:

    # 再定义一个类
    class Payment:
        def pay(self,money):
            raise NotImplementedError  # 报没有实现这个方法的错误,所以可以知道前面错误的地方就应该存在与pay同名的方法
    
    class Wechatpay(Payment):  # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类
        def pay(self,money):
            print('已经使用微信支付了%s元' % money)
    
    class Alipay(Payment):
        def pay(self,money):  # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类
            print('已经使用支付宝支付了%s元' % money)
    
    # 再定义一个Applepay类
    class Aapplepay(Payment):
        # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类,因为这里面没有pay函数,
        # 所以执行父类,所以最后将会报’NotImplementedError‘的错误
        def fuqian(self,money):  # 这里不是使用pay函数
            print('已经使用苹果支付了%s元' % money)
    
    def pay(pay_obj,money):
        # 统一支付入口,不管使用哪种方式,主要就是支付就可以了
        pay_obj.pay(money)
    
    wechat = Wechatpay()
    # 实例化
    ali = Alipay()
    # 实例化
    app = Aapplepay()
    # 实例化
    pay(wechat,100)  # 通过微信支付100
    pay(ali,200)  # 通过支付宝支付200
    pay(app,300)  # 这里调用pay函数,但是前面Applepay里面使用的不是pay函数而是fuqian,所以这里结果将会报错

    运行结果:

    已经使用微信支付了100元
    Traceback (most recent call last):
    已经使用支付宝支付了200元
      File "<encoding error>", line 33, in <module>
      File "<encoding error>", line 23, in pay
      File "<encoding error>", line 4, in pay
    NotImplementedError

      从代码中可以看到,只要你支付方式里面不存在pay的函数方法,就会直接执行父类payment里面的pay方法,从而后面直接报自己写的错误,这样可以提示出错的支付方式里面应该存在

    与父类中的pay方法一样的方法或者函数,但是这样的报错方法必须要通过调用pay方法后才能找出错误,如果要在不对pay方法进行调用的情况下就可以找到错误的地方,这样的代码改进如下:

    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):  # 默认的元类type
        @abstractmethod
        def pay(self,money):
            pass
    # 只要使用了以上这样的方法就表明已经建立一个规范,规范下面所有的代码,使得以下的代码都应该存在与pay同名的方法,
    # 不存在就无法进行,就会报错,而且报错方法还会具体指出错误所在
    
    class Wechatpay(Payment):  # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类
        def pay(self,money):
            print('已经使用微信支付了%s元' % money)
    
    class Alipay(Payment):
        def pay(self,money):  # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类
            print('已经使用支付宝支付了%s元' % money)
    
    # 再定义一个Applepay类
    class Aapplepay(Payment):
        # 继承Payment类,但是先找自己里面是否有pay函数,有就用自己的,没有才找父类,因为这里面没有pay函数,
        # 所以执行父类,所以最后将会报’NotImplementedError‘的错误
        def fuqian(self,money):  # 这里不是使用pay函数
            print('已经使用苹果支付了%s元' % money)
    
    def pay(pay_obj,money):
        # 统一支付入口,不管使用哪种方式,主要就是支付就可以了
        pay_obj.pay(money)
    
    wechat = Wechatpay()
    # 实例化
    ali = Alipay()
    # 实例化
    app = Aapplepay()
    # 实例化
    # 使用了开头的规范后,就不需要在进行调用方法pay才可以报错了了,直接进行实例化就可以,
    # 这样方便写代码的人很快就可以找出错误所在
    # pay(wechat,100)  # 通过微信支付100
    # pay(ali,200)  # 通过支付宝支付200
    # pay(app,300)  # 这里调用pay函数,但是前面Applepay里面使用的不是pay函数而是fuqian,所以这里结果将会报错

    运行结果:

    Traceback (most recent call last):
      File "<encoding error>", line 32, in <module>
    TypeError: Can't instantiate abstract class Aapplepay with abstract methods pay

    这样就可以引出用代码实现接口类的大致结构,类似的结构如下所示:

    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):  # 默认的元类type
        @abstractmethod
        def pay(self,money):  # 规范子类必须含有pay方法
            pass
    class A(Payment):
        def pay(self,money):pass
    
    class B(Payment):
        def pay(self,money):pass
    
    class C(Payment):
        def pay(self,money):pass

    其实接口类和抽象类都是起到一个规范子类,约束子类的一个作用,不同的地方是:

    接口类:支持多继承,接口类中的所有方法都必须不能实现,这样才能起到规范的作用---Java中

    抽象类:不支持多继承,抽象类中的方法可以有一些代码的实现---Java中

  • 相关阅读:
    POJ训练计划1035_Spell checker(串处理/暴力)
    软考-数据库与标准化和知识产权
    分析Cocos2d-x横版ACT手游源码 1、公共
    增强版的RecycleViewAdapter,能够直接使用
    高考志愿,你们想好怎么填了吗?
    win32收不到F10按键消息解决的方法
    Json——使用Json jar包实现Json字符串与Java对象或集合之间的互相转换
    九度OJ #1437 To Fill or Not to Fil
    SQL数据分组后取最大值或者取前几个值(依照某一列排序)
    3.5星|《硅谷产品》:Facebook网红社区产品经理经验谈
  • 原文地址:https://www.cnblogs.com/wxm422562/p/11006498.html
Copyright © 2020-2023  润新知