接口类

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

2、例子:

第一步:每定义一种支付类,就通过实例化对象调用相应的支付方法,这样虽然也可以实现QQ支付和支付宝支付,但代码风格不统一
class QQPay():
def pay(self, money):
print('QQ支付了%s元' %money) class AliPay():
def pay(self, money):
print('支付宝支持了%s元' %money)
qq1 = QQPay()
ali1 = AliPay()
qq1.pay(100)
ali1.pay(200) 结果:
QQ支付了100元
支付宝支持了200元 第二步:定义一个统一支付的函数,通过将实例化对象作为参数传递给这个函数,由函数来执行实例化对象的pay方法
class QQPay():
def pay(self, money):
print('QQ支付了%s元' %money) class AliPay():
def pay(self, money):
print('支付宝支持了%s元' %money) def pay(obj, money):
obj.pay(money) qq1 = QQPay()
ali1 = AliPay() pay(qq1, 100)
pay(ali1, 200)
结果:
QQ支付了100元
支付宝支持了200元 第三步:如果代码后期需要增加新的支付方式,而这时开发人员已经更换,新的开发人员并没有依照原来的代码风格进行统一编写,虽然也可以执行,但又破坏了代码统一性
class WechatPay(payment):
def fuqian(self, money):
print('微信支付了%s元' %money) wechat1 = WechatPay()
结果:微信支付了300元 第四步:我们先定义一个父类,什么都不写,只是要求继承我的所有类有一个pay方法,这样就制定了一个规范,这就叫做接口类,或者抽象类.
class payment:
def pay(self):
pass 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 pay(self, money):
print('微信支付了%s元' %money) def pay(obj, money):
obj.pay(money) qq1 = QQPay()
ali1 = AliPay()
wechat1 = WechatPay() pay(qq1, 100)
pay(ali1, 200)
pay(ali2, 300) 结果:
QQ支持了100元
支付宝支持了200元
微信支付了300元 但是这样如果新增的方法WechatPay仍然没有遵循父类中的格式,还是写成了下面这样也还是可以执行的
class WechatPay(payment):
def fuqian(self, money):
print('微信支付了%s元' %money)
wechat1 = WechatPay()
wechat1.fuqian(300) 第五步:那么如何强制让新增的类遵循统一格式呢,需要使用@abstractmethod方法
from abc import ABCMeta, abstractmethod class payment(metaclass=ABCMeta):
@abstractmethod
def pay(self):
pass 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) qq1 = QQPay()
ali1 = AliPay()
wechat1 = WechatPay() pay(qq1, 100)
pay(ali1, 200)
wechat1.fuqian(300)
这时如果WechatPay里面方法名称不是pay,那么结果会报错,TypeError: Can't instantiate abstract class WechatPay with abstract methods pay
所以这时就必须要求WechatPay里面存在pay方法,程序才能正确执行,这样就可以使用统一的pay函数进行统一调用对象,
代码修改如下:
class WechatPay(payment):
def pay(self, money):
print('微信支付了%s元' %money) qq1 = QQPay()
ali1 = AliPay()
wechat1 = WechatPay() pay(qq1, 100)
pay(ali1, 200)
pay(wechat1, 300) 备注:经测试,其实子类中只要有父类中的方法pay即可,即使写成下面这样也还是可以执行。。。
class WechatPay(payment):
def fuqian(self, money):
print('微信支付了%s元' %money)
def pay(self):
pass wechat1 = WechatPay()
wechat1.fuqian(300) 也可以将对象放在一个字典中进行循环调用
def pay(obj, money):
obj.pay(money) qq1 = QQPay()
ali1 = AliPay()
wechat1 = WechatPay() pay_dict = {qq1: 100, ali1: 200, wechat1: 300}
for i in pay_dict:
pay(i, pay_dict[i]) QQ支持了100元
支付宝支持了200元
微信支付了300元

实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

继承的第二种含义非常重要。它又叫“接口继承”。

接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合

依赖倒置原则:
1)高层模块不应该依赖低层模块,二者都应该依赖其抽象;

2)抽象不应该依赖细节,细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程

在python中根本就没有一个叫做interface的关键字,上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,如果非要去模仿接口的概念,可以借助第三方模块:
http://pypi.python.org/pypi/zope.interface
twisted的twisted\internet\interface.py里使用zope.interface
文档https://zopeinterface.readthedocs.io/en/latest/
设计模式:https://github.com/faif/python-patterns

接口提取了一群类共同的函数,可以把接口当做一个函数的集合,然后让子类去实现接口中的函数。
这么做的意义在于归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,用法都一样。

归一化,让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不出哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。

再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

抽象类

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

2、为什么要有抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。

从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的

3、抽象类与接口类
抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。
抽象类是一个介于类和接口之间的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念。

day24-抽象类与接口类的更多相关文章

  1. php 抽象类和接口类

    PHP中抽象类和接口类都是特殊类,通常配合面向对象的多态性一起使用. 相同: ①两者都是抽象类,都不能实例化. ②只有接口类的实现类和抽象类的子类实现了 已经声明的 抽象方法才能被实例化. 不同: ① ...

  2. python之路----继承的抽象类和接口类

    抽象类与接口类 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数 ...

  3. Python抽象类和接口类

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

  4. python基础 抽象类(接口类)

    Python中没有接口.接口类,抽象类:定义 制定一个规范 #必须要导入from abc import ABCMeta,abstractmethod class Payment(metaclass = ...

  5. 抽象类,接口类,封装,property,classmetod,statimethod

    抽象类,接口类,封装,property,classmetod,statimethod(类方法,静态方法) 一丶抽象类和接口类 接口类(不崇尚用) 接口类:是规范子类的一个模板,只要接口类中定义的,就应 ...

  6. python's twenty-first day for me 抽象类和接口类以及多态

    归一化设计: 不管是哪一个类的对象,都调用同一个函数去完成相似的功能. class Alipay: def pay(self,money): print('使用支付宝支付了%s' % money) c ...

  7. Python面向对象 | 抽象类和接口类

    一.抽象类(规范的编程模式) 什么是抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化.抽象类的本质还是类,指的是一组类的相似性,而接口只强调函数属性的相似性. 为什么要有抽象类 ...

  8. PHP的抽象类、接口类的区别和选择【转载】

    本文转自:http://blog.csdn.net/fanteathy/article/details/7309966 区别: 1.对接口的使用是通过关键字implements.对抽象类的使用是通过关 ...

  9. python 抽象类和接口类

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

  10. abstract class和interface 抽象类与接口类的区别

    抽象类与类型定义相关: 接口类与行为规范相关: 接口类不是类型. 抽象类:是不完整的类,函数实现未定义:可以继承,不可以实例化. 接口类:接口类不是类:是类间交互的规范:不能继承.不能实例化,只能实现 ...

随机推荐

  1. PAT 乙级 1079 延迟的回文数(20 分)

    1079 延迟的回文数(20 分) 给定一个 k+1 位的正整数 N,写成 a​k​​⋯a​1​​a​0​​ 的形式,其中对所有 i 有 0≤a​i​​<10 且 a​k​​>0.N 被称 ...

  2. Git revert及其他一些回退操作

    放弃本地的代码和本地提交,希望会退到远程分支的某次提交时,使用git reset --hard fa042ce. 本地已提交,但是发现有问题,想要撤销本地的提交,使用git checkout /trs ...

  3. centos 7扩展磁盘分区容量

    一.fdisk -l 查看磁盘空间大小 二. 1.fdisk /dev/sda 增加分区 2.判断应增加的分区号 键入n,增加一个分区 3.键入p,主分区,并键入(编号) 4.起始扇区和结束扇区(默认 ...

  4. 知识点:Navicet Mysql数据库电脑本地备份

    Navicet Mysql数据库电脑本地备份 1.打开navicat客户端,连上mysql后,双击左边你想要备份的数据库.点击“计划”,再点击“新建批处理作业”.     2.双击上面的可用任务,它就 ...

  5. c#属性 ——面向对象

    String. Format(字符串格式化输出) 相当于Console.WriteLine(字符串格式化输出); 而String.Format是返回一个字符串 属性: 因为把字段全public,会非常 ...

  6. FileMaker Server 15 Windows 安装

    FileMaker 国外流行,国内研究的人不多.这玩意的好处是: 标准的数据库软件,同时带界面,相当于Access. 手机上安装FileMaker Go,Windows & IOS上安装 Fi ...

  7. 第11章 拾遗4:IPv6(2)_给计算机配置IPv6地址

    4. 给计算机配置IPv6地址 4.1 无状态自动配置IPv6地址 (1)网络拓扑 ①无状态地址自动配置是指不需要DHCP服务器进行管理,由客户端向路由器发送前缀请求(RS)询问其所在网段.路由器收到 ...

  8. Linux下用node-inspector实现NodeJS远程调试开发

    1.首先安装 node-inspector npm install -g node-inspector -g表示全局安装,如果像我一样安装失败,再试几次,npm偶尔就会这样抽风... 这一步是关键的, ...

  9. TextView右上角显示小红点,小红点根据TextView的长度移动,小红点被TextView挤出去不显示的问题;

    大概就是图片这个样,这个功能很常见,本来我以为很简单,谁知道真的很简单: 遇到点小问题,记录一下,哈哈: 小红点的Drawable: <?xml version="1.0" ...

  10. SQL获取连续数字中断数字

    表A -- 创建结果表 create table #u(LostA int) declare @minA int,@maxA int set @minA=(select min(ID) from A) ...