接口类

继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)和声明某个子类兼容于某基类,定义一个接口类interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口的功能

比如说一种支付方式有三种不同的途径:Alipay、Applepay、Wechatpay

如果现在只有两种支付方式Alipay和Wechatpay,我们该如何去实现支付的方法呢?

class Wechat:
def pay(self,money):
print('已经用了微信支付了%s元'%money)
class Alipay:
def pay(self,money):
print('已经用了支付宝支付了%s元'%money)
wechat = Wechat()
wechat.pay(200) #已经用了微信支付了200元
ali = Alipay()
ali.pay(150) #已经用了支付宝支付了150元

但是这样做有一点不好就是用户要去关心他在支付的时候是用什么方式去pay的,而我们只需要传一个支付的对象和钱就好了

def pay(obj_pay,money):     #定义一个支付函数
obj_pay.pay(money)
class Wechat:
def pay(self,money):
print('已经用了微信支付了%s元'%money)
class Alipay:
def pay(self,money):
print('已经用了支付宝支付了%s元'%money)
wechat = Wechat()
pay(wechat,300) #已经用了微信支付了300元
ali = Alipay()
pay(ali,250) #已经用了支付宝支付了250元

这样写虽然可以,但是假设在之后添加了一个新的类Applepay的付款方式,里面的方法名和pay名不同就会导致报错

from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
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 Apple(Payment):
def payMoney(self,money):
print('已经用了支付宝支付了%s元'%money) wechat = Wechat()
ali = Alipay()
apple = Apple() #Can't instantiate abstract class Apple with abstract methods pay

这样的话如果开发人员写的方法名和pay不同时,程序在实例化对象就会报错就直接给给开发人员提示了要用规范的方法去写。如果我们再把Apple类中的方法给改回pay的方法名,那么就不会报错了

class Apple(Payment):
def pay(self,money):
print('已经用了支付宝支付了%s元'%money) apple = Apple()

接口的多继承

如果我们归纳下面三种动物的行为,老虎能走路、游泳;天鹅能飞、走路、游泳;老鹰能走路、飞,我们该如何用接口的方法去表示呢?

from abc import abstractmethod,ABCMeta
class Swim_Behavior(metaclass=ABCMeta):
@abstractmethod
def swim(self):
pass
class Walk_Behavior(metaclass=ABCMeta):
@abstractmethod
def walk(self):
pass
class Fly_Behavior(metaclass=ABCMeta):
@abstractmethod
def fly(self):
pass class Tiger(Swim_Behavior,Walk_Behavior):
def walk(self):
print('Can walk!')
def swim(self):
print('Can swim!') class Swan(Swim_Behavior,Walk_Behavior,Fly_Behavior):
def walk(self):
print('Can walk!')
def swim(self):
print('Can swim!')
def fly(self):
print('Can fly!') class Hawk(Walk_Behavior,Fly_Behavior):
def walk(self):
print('Can walk!')
def fly(self):
print('Can fly!') t = Tiger()
s = Swan()
h = Hawk()

接口类本身的方法不实现只是起到规范的作用

接口隔离原则:

使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口

专门的接口指的是上面的动物能walk就用walk的接口,能fly就用fly的接口,能swim就用swim的接口

不使用单一的接口指的是不应该使用一个接口里面既能有walk的行为又有fly的行为等,只有这样把每一个功能都隔离开,我们在后面用到这个功能就能够继承到它所有相关变量名和方法名

即客户端不应该依赖那些不需要的接口指的是创建了一个Tiger类不应该要那些自己本身没有的类,比如fly

抽象类

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

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

#在操作系统中一切皆文件
from abc import abstractmethod,ABCMeta
class All_file(metaclass=ABCMeta):
all_type = 'file' #所有的类型都是文件
@abstractmethod #定义一个抽象方法无需实现功能
def write(self):
pass
@abstractmethod #定义一个抽象方法无需实现功能
def read(self):
pass class Txt(All_file): #定义一个Txt类,子类继承抽象类,但是必须定义一个write和read的方法
def write(self):
print('Write something...')
def read(self):
print('Read something...') class Sata(All_file): #定义一个Sata类,子类继承抽象类,但是必须定义一个write和read的方法
def write(self):
print('Write something...')
def read(self):
print('Read something...') txt = Txt()
sata = Sata() txt.read() #Read something...
txt.write() #Write something...
sata.read() #Read something...
sata.write() #Write something...
print(txt.all_type) #file
print(sata.all_type) #file

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

接口类和抽象类总结

在python中没有接口类,但有抽象类;abc模块中的metaclass = ABCMeta,@abstractmethod它的本质是做代码的规范用的,希望子类中能实现父类名字完全一样的方法

接口类和抽象类:

从java的角度上看是有区别的,java本来就支持单继承所以就有了抽象类;java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承了

而python它既支持单继承也支持多继承,所以对于接口类和抽象类的区别就不会那么明显了,甚至在python中没有内置接口类

多态

多态指的是一类事物有多种形态

python天生支持多态

from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta): #支付方式类
@abstractmethod
def pay(self,money):
pass class Wechat(Payment): #支付方式---微信支付
def pay(self,money):
print('已经用了微信支付了%s元'%money)
class Alipay(Payment): #支付方式---支付宝支付
def pay(self,money):
print('已经用了支付宝支付了%s元'%money)
class Apple(Payment): #支付方式---苹果支付
def pay(self,money):
print('已经用了支付宝支付了%s元'%money)

多态性

就是虽然是一类东西但是它们执行的是相同的方法但是做的是不同的事,比如微信它用的是微信支付、支付宝它用的是支付宝支付、苹果支付它用的是苹果支付...

鸭子类型

python语言里面有一个鸭子类型的概念,而在某些其他的属于强类型语言,用的是多态

鸭子类型:不崇尚根据继承所得来的相似,我只是自己实现我自己的代码就可以了,如果有两个类它们刚好相似,并不产生父类的子类的兄弟关系,那这就是鸭子类型。像list、tuple这种相似,是自己写代码的时候约束的,而不是通过父类约束的

Python学习日记(二十五) 接口类、抽象类、多态的更多相关文章

  1. Python学习日记(二十八) hashlib模块、configparse模块、logging模块

    hashlib模块 主要提供字符加密算法功能,如md5.sha1.sha224.sha512.sha384等,这里的加密算法称为摘要算法.什么是摘要算法?它又称为哈希算法.散列算法,它通过一个函数把任 ...

  2. Python学习(二十五)—— Python连接MySql数据库

    转载自http://www.cnblogs.com/liwenzhou/p/8032238.html 一.Python3连接MySQL PyMySQL 是在 Python3.x 版本中用于连接 MyS ...

  3. Python学习札记(二十五) 函数式编程6 匿名函数

    参考:匿名函数 NOTE 1.Python对匿名函数提供了有限的支持. eg. #!/usr/bin/env python3 def main(): lis = list(map(lambda x: ...

  4. Python学习日记(二十九) 网络编程

    早期的计算机通信需要有一个中间件,A要给B传东西,A必须要把信息传给中间件,B再把从中间件中拿到信息 由于不同机器之间需要通信就产生了网络 软件开发的架构 1.C/S架构 服务器-客户机,即Clien ...

  5. Python学习日记(二十六) 封装和几个装饰器函数

    封装 广义上的封装,它其实是一种面向对象的思想,它能够保护代码;狭义上的封装是面向对象三大特性之一,能把属性和方法都藏起来不让人看见 私有属性 私有属性表示方式即在一个属性名前加上两个双下划线 cla ...

  6. Python学习日记(二十四) 继承

    继承 什么是继承?就是一个派生类(derived class)继承基类(base class)的字段和方法.一个类可以被多个类继承;在python中,一个类可以继承多个类. 父类可以称为基类和超类,而 ...

  7. Python学习日记(二十二) 初识面向对象

    引子 假设我们要开发一个关于飞机大战的游戏,那么游戏的里面就会有两个角色,分别是属于玩家操控的战机和敌方的战机,并且两个战机都有不同的技能或攻击方式,现在我们用自己目前所学的去写出下面的这些代码: d ...

  8. PHP学习笔记二十五【类的继承】

    <?php //定义父类 class Stu{ public $name; protected $age; protected $grade; private $address;//私有变量不会 ...

  9. python学习(二十五) 链表方法

    # 链表 cars = ['a', "b"] print(cars) # 链表长度 print(len(cars)) # 结尾添加元素 cars.append("c&qu ...

随机推荐

  1. 搭建Bitcoin全节点

    节点搭建 1. 进入 bitcoin 选择 Choose your wallet 2. 选择 Bitcoin Core for Linux 下载 bitcoin-0.17.0.1-x86_64-lin ...

  2. maven引入CDH依赖包

    1. POM文件加入仓库 注意:id要和仓库配置中的id一致. <repositories> <repository> <id>cloudera</id> ...

  3. SEO前端篇(二)关键词

    首先要SEO的关键词最好放在网站首页index,并且网站域名选用顶级域名,最好是.com.现在很多后缀的域名不能备案,选择域名的时候一定要慎重. 域名解析的主机IP最好选择站点资源少的区域,可以用 爱 ...

  4. 【LeetCode算法-21】Merge Two Sorted Lists

    LeetCode第21题 Merge two sorted linked lists and return it as a new list. The new list should be made ...

  5. haproxy2.0入门部署教程

    测试后发现,haproxy2.0和之前的版本部署有些许差异,配置文件的写法也是不同的 测试环境:Centos7.3 IP:172.16.1.227 172.16.1.228 部署httpd,页面内容为 ...

  6. close yarn install --check-files

    To disable this check, please add `config.webpacker.check_yarn_integrity = false` to your Rails deve ...

  7. Indy10 Tcp接收数据问题

    在做Delphi开发时,使用Indy组件来做网络通讯是一种比较快捷的方式.今天要说一下indy10中tcp接收数据的问题. 我们在测试时经常使用Wrinteln来发送数据,用Readln来接收数据.用 ...

  8. tp5之服务器不显示验证码

    今天在使用tp框架的时候遇到的一个bug,前辈们早已有解决方法,遇到了做个笔记 TP5框架,自带的验证码在本地localhost运行是没问题的,可以正常显示,如图: 然后,把框架拿到服务器是去运行,验 ...

  9. Centos7修改profile错误的解救方案

    在改profile的时候,改出问题了,除了cd以外的命令基本都不能用了.使用root用户执行: # export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11 ...

  10. 自定义 Word 默认的 Normal.dotm 模板、更改 Word 默认字体、更改 Word 默认样式(16)

    1. 引言 以Office 2016为例. 有没有遇见这样的问题: 每次新建一个 Word 空白文档打开后字体默认是等线,段落默认是单倍行距,默认标题也不是自己想要的样式,等一系列问题.每次打开都要调 ...