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

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

 

posted @ 2019-03-28 17:55  亚里士多缺德  阅读(96)  评论(0编辑  收藏  举报