• 面向对象 -- 三大特性之继承 补充 抽象类 接口类


    type 和 class

    type 一个对象的时候,结果总是这个对象所属的类

    那么类是什么类型?

    所有的类的类型都是type

    type 是所有类型的鼻祖

    type( 类名 ) = type

    类也是被创造出来的 可以由python解释器创造 也可以由特殊的方法创造

    常规创造的类 总是有几个特性

    能够实例化  能有属性  能有方法一些有特殊需求的类

    所有的用class常规语法创造出来的类 都是type类型

    元类

    能帮你创造出不同寻常的类

    可以实现特殊的需求 例如 不能实例化  只能有一个实例

    抽象类

    类的约束

    不同的类,要使用的方法相同,但如果有一个类的方法名字写错了 调用方法的时候会很麻烦

    class Wechatpay:
        def __init__(self,name,money):
            self.name = name
            self.money = money
        def pay(self):
            print('%s通过微信支付了%s元'%(self.name,self.money))
    
    class Alipay:
        def __init__(self,name,money):
            self.name = name
            self.money = money
        def pay(self):
            print('%s通过支付宝支付了%s元'%(self.name,self.money))
    
    class ApplePay:
        def __init__(self,name,money):
            self.name = name
            self.money = money
        def fuqian(self):
            print('%s通过apple pay支付了%s元' % (self.name, self.money))
    
    
    # 归一化设计
    def pay(person):
        person.pay()
    
    
    wcp = Wechatpay('alex',2000000)
    pay(wcp)
    ali = Alipay('alex',2000000)
    
    app = ApplePay('alex',2000000)
    pay(app)
    
    代码的规范没有建立起来

    所以此时我们要用到对类的约束,对类的约束有两种:

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

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

    先用第一种方式解决:

    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)

    第二种方法:

    引入抽象类的概念处理

    from abc import ABCMeta,abstractmethod
    class Payment(metaclass=ABCMeta):    # 抽象类
    
        @abstractmethod   # 如果我必须要实现pay方法,那么我需要给pay加一个装饰器
        def pay(self):
            pass   # 创建的这个pay并没有内容,
                   # 之所以写一个pay是为了提醒所有子类你一定要实现一个pay方法
                   # 如果子类没有使用这两个方法,就会报错
        @abstractmethod
        def back(self):
            pass
    
    class Wechatpay(Payment):
        def __init__(self,name,money):
            self.name = name
            self.money = money
        def pay(self):
            print('%s通过微信支付了%s元'%(self.name,self.money))
        def back(self):
            print('退款')
    
    class Alipay(Payment):
        def __init__(self,name,money):
            self.name = name
            self.money = money
        def pay(self):
            print('%s通过支付宝支付了%s元'%(self.name,self.money))
        def back(self):
            print('退款')
    
    class ApplePay(Payment):
        def __init__(self, name, money):
            self.name = name
            self.money = money
        def pay(self):
            print('%s通过apple pay支付了%s元' % (self.name, self.money))
        def back(self):
            print('退款')
    
    
    w = Wechatpay('alex',200)
    w.pay()
    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,
    # 那么这个类就变成了一个抽象类(接口类)
    # 这个类的主要功能就是建立一个规范

    总结

    约束. 其实就是⽗类对⼦类进⾏约束. ⼦类必须要写xxx⽅法. 在python中约束的⽅式和⽅法有两种:

    1. 使⽤抽象类和抽象⽅法, 由于该⽅案来源是java和c#. 所以使⽤频率还是很少的

    2. 使⽤⼈为抛出异常的⽅案. 并且尽量抛出的是NotImplementError. 这样比较专业, ⽽且错误比较明确.(推荐)

    接口类

    java中没有多继承的类

    所以抽象类 只能是所有的子类只有一个规范

    于是发明了接口 接口可以多继承

    在python中没有接口专用语法

    只是通过类的多继承 模仿接口效果

    抽象类是单继承的规范  接口类是多继承的规范

    from abc import ABCMeta,abstractmethod
    class NormalAnnimal(metaclass=ABCMeta):
        @abstractmethod
        def eat(self):pass
    
        @abstractmethod
        def drink(self):pass
    class FlyAnimal(metaclass=ABCMeta):
        @abstractmethod
        def fly(self):pass
    
    class SwimAnimal(metaclass=ABCMeta):
        @abstractmethod
        def swim(self):pass
    
    class WalkAnimal(metaclass=ABCMeta):
        @abstractmethod
        def walk(self):pass
    
    
    class Frog(NormalAnnimal,SwimAnimal,WalkAnimal):
        def eat(self):
            pass
    
    
    class Tiger(NormalAnnimal,SwimAnimal,WalkAnimal):pass
    class Swan(NormalAnnimal,FlyAnimal,SwimAnimal,WalkAnimal):pass
    class Parrot(NormalAnnimal,FlyAnimal,WalkAnimal):
        def talk(self):
            pass
  • 相关阅读:
    String,StringBuffer,StringBuilder简单对比
    Java基本数据类型
    EasyMock框架的使用详解
    Python3.6在win7中无法正常运行的问题
    zabbix3.4源码安装步骤
    hadoop_2.6.5集群安装
    Cassandra2.2.10安装过程
    JDK1.8安装
    zookeeper3.4.6安装
    python3.6的安装及cx_oracle安装
  • 原文地址:https://www.cnblogs.com/biulo/p/10616680.html
Copyright © 2020-2023  润新知