接口类

接口类:python原生不支持的
抽象类:python原生支持的

导引:写一个支付的程序

class Wechat:
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay:
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

wechat=Wechat()
wechat.pay(100)

Ali=Alipay()
Ali.pay(100)

这段代码初步实现了支付的功能,但是在实际使用的时候不关心消费者使用的是什么支付方式,只要收钱就可以

class Wechat:
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay:
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj
    pay_obj.pay(money)

wechat=Wechat()
Ali=Alipay()
pay(wechat,100)
pay(Ali,100)

进阶

class Wechat:
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay:
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

class Appplepay:
    def fuqian(self,money):#假如新来的员工不会写英文,那么这里就出现了中文的fuqian
        print('使用Appplepay支付了%s元' % money)

def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj
    pay_obj.pay(money)

wechat=Wechat()
Ali=Alipay()
App=Appplepay()
pay(wechat,100)
pay(Ali,100)
pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错

那么如何出现这个报错呢

class Payment:
    def pay(self,money):
        raise NotImplemented#这里表示没有实现这个功能

class Wechat(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay(Payment):
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

class Appplepay(Payment):
    def fuqian(self,money):#假如新来的员工不会写英文,那么这里就出现了中文的fuqian
        print('使用Appplepay支付了%s元' % money)

def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj
    pay_obj.pay(money)

wechat=Wechat()
Ali=Alipay()
App=Appplepay()
pay(wechat,100)
pay(Ali,100)
pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错

D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py
使用微信支付了100元
Traceback (most recent call last):
使用支付宝支付了100元
  File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 25, in <module>
    pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错
  File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 18, in pay
    pay_obj.pay(money)
  File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 3, in pay
    raise NotImplemented#这里表示没有实现这个功能
TypeError: exceptions must derive from BaseException

Process finished with exit code 1

这里,将支付的方法定义为一个父类,然后继承,当下面支付的函数,如果没有按照父类中的形式来写的时候,就会报错,这样一看到出现这个错误,就知道在下面的支付方式的地方写错了

当修改了苹果pay后的代码

class Payment:
    def pay(self,money):
        raise NotImplemented#这里表示没有实现这个功能

class Wechat(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay(Payment):
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

class Appplepay(Payment):
    def pay(self,money):#修改为pay
        print('使用Appplepay支付了%s元' % money)

def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj
    pay_obj.pay(money)

wechat=Wechat()
Ali=Alipay()
App=Appplepay()
pay(wechat,100)
pay(Ali,100)
pay(App,100)
D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py
使用微信支付了100元
使用支付宝支付了100元
使用Appplepay支付了100元

Process finished with exit code 0

上面的代码运行正常

正式引入接口类的定义

from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):pass
#这里的规范对于下面只是一个约束的作用,规范了支付的正式写法。这里就是一个接口类
#接口类:默认多继承,所有的方法都必须不能实现,就是方法后面是pass——java
#抽象类:不支持多继承,抽象类中可以有些代码的实现——java

class Wechat(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)

class Alipay(Payment):
    def pay(self,money):
        print('使用支付宝支付了%s元' % money)

class Appplepay(Payment):
    def fuqian(self,money):#修改为pay
        print('使用Appplepay支付了%s元' % money)

def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj
    pay_obj.pay(money)

wechat=Wechat()
Ali=Alipay()
App=Appplepay()
pay(wechat,100)
pay(Ali,100)
pay(App,100)

 接口类的多继承

导引,进入动物园,希望利用函数能够描述所有动物的行为,但是下面的显然不能满足要求

class Animal:
    def walk(self):
        pass
    def flying(self):
        pass
    def swim(self):
        pass

Tiger=Animal()#但是老虎不会游泳

可以这样

class Swan:
    def walk(self):
        pass
    def flying(self):
        pass

class Hawk:
    def walk(self):
        pass
    def flying(self):
        pass

class Tiger:
    def walk(self):
        pass
    def flying(self):
        pass

实现了功能,但是代码数量太多

此时可以使用接口类的多继承

首先是继承

class Swim_Animal:
    def swim(self):
        pass

class Walk_Animal:
    def swim(self):
        pass

class Fly_Animal:
    def swim(self):
        pass

class Tiger(Walk_Animal,Swim_Animal):pass
class Hawk(Fly_Animal,Fly_Animal):pass
class Swan(Walk_Animal,Fly_Animal):pass

其次,这里面有很多的同类型的代码,那么防止写错就需要用到接口

from abc import abstractmethod,ABCMeta
class Swim_Animal:
    @abstractmethod
    def swim(self):
        pass

class Walk_Animal:
    @abstractmethod
    def walk(self):
        pass

class Fly_Animal:
    @abstractmethod
    def fly(self):
        pass

class Tiger(Walk_Animal,Swim_Animal):
    def walk(self):
        pass

    def swim(self):
        pass


class Hawk(Fly_Animal,Walk_Animal):pass
class Swan(Walk_Animal,Fly_Animal):pass

抽象类

什么是抽象类

    与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

为什么要有抽象类

    如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同的内容而来的,内容包括数据属性和函数属性。

  比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。

    从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案

#在操作系统中一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

# class Txt(All_file):
#     pass
#
# t1=Txt() #报错,子类没有定义抽象方法

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

一般情况下,单继承能够实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
多继承的情况,由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中。

比如

#在操作系统中一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
         with open('filename') as f:
             pass#这样能够将下面对文件的操作提到上面来

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

python中没有接口类,java里不支持多继承,所以它创造了接口interface这个概念,那么interface这个数据类型就能够在java中实现多继承。不能实例化
python中自带多继承,所以我们直接哦那个class来实现了接口类
python中支持抽象类,一般情况下单继承,因为java里面抽象类只支持单继承;

java里面所有的继承都是单继承,所以抽象类完美的解决了单继承需求中的规范问题。
但对于多继承的需求,由于java本身的语法不支持,所以创建了接口interface这个概念来解决多继承的问题

 

python中没有接口类,但是有抽象类,通过abc模块中的metacclass=ABC,@abstrud
本质是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法
接口类和抽象类的区别:
在java的角度看是有区别的:
java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承
java本来就支持单继承,所以就有了抽象类。
python既支持单继承也支持多继承,所以对于接口类和抽象类的区别就不那么明显了
甚至在python中并没有内置接口类

posted @ 2019-03-10 22:37  舒畅123  阅读(131)  评论(0编辑  收藏  举报