接口类

继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)和声明某个子类兼容于某基类,定义一个接口类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. Amazon | OA 2019 | Optimal Utilization

    Given 2 lists a and b. Each element is a pair of integers where the first integer represents the uni ...

  2. 【转】HTML meta标签总结与属性使用介绍

    HTML meta标签总结与属性使用介绍 转载处写的已经超级好了,强烈推荐. 转自:https://segmentfault.com/a/1190000004279791 本人就不再赘述.拿来主义!供 ...

  3. Swift编码总结7

    1.Git 打Tag: 命令也就下面两条,看看就会了. 2.字符串转Model:JSONDecoder http://www.cocoachina.com/ios/20180612/23771.htm ...

  4. Oracle current redo.log出现坏块后的不完全恢复案例一则

    1异常出现      8月30日下午2时左右,接同事电话,说数据库异常宕机了,现在启动不了. 2初步分析 我让现场把alert.log发过来,先看看是什么问题.   关于ORA-00353和ORA-0 ...

  5. maven设置阿里云仓库

    到maven安装目录的conf下setting.xml文件 找到mirrors标签中添加 <mirror> <id>nexus-aliyun</id> <mi ...

  6. 问题三:Appium 的 UIAutomator2 模式下使用 sendKeys 出现错误

    在Appium默认的模式下,可以对TextFiled控件进行sendKeys操作: 设置capabilities.setCapability("automationName",&q ...

  7. Centos安装nodejs,并运行项目

    不建议编译安装,对gcc要求比较高 安装nodejs yum install nodejs nodejs升级 npm i -g n --force n stable npm升级 npm install ...

  8. react中使用typescript时,error: Property 'setState' does not exist on type 'Home'

    问题描述: 我在react中用typescript时,定义一个Home组件,然后在组件里用setState时会有这样一个报错:(如图)Property 'setState' does not exis ...

  9. 统一封装json返回结果

    import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.annotate.JsonSerial ...

  10. 使用Python快速实现简单的人脸检测

    最近有个比较要好的朋友问我能不能从监控视频里识别到从监控跟前经过的指定的人.因为他们单位的监控室经常要花大量的人力跟时间去找某个人在哪个位置出现过的证据.听起来像是一份比较有挑战性的任务,就答应他试试 ...