python--接口类与抽象类
一、
继承有两种用途:
"""
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)
且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
三、接口隔离原则:使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口
"""
"""
接口类:基于同一个接口实现的类 刚好满足接口隔离原则 面向对象开发的思想 规范
接口类,python 原生不支持 在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念
"""
一、接口类单继承
我们来看一段代码去了解为什么需要接口类
class Alipay:
def pay(self,money):
print('支付宝支付了')
class Apppay:
def pay(self,money):
print('苹果支付了')
class Weicht:
def pay(self,money):
print('微信支付了')
def pay(payment,money): # 支付函数,总体负责支付,对应支付的对象和要支付的金额
payment.pay(money)
p=Alipay()
pay(p,200) #支付宝支付了
这段代码,实现了一个有趣的功能,就是通过一个总体的支付函数,实现了不同种类的支付方式,不同是支付方式作为对象,传入函数中
但是开发中容易出现一些问题,那就是类中的函数名不一致,就会导致调用的时候找不到类中对应方法,例题如下:
class Alipay:
def paying(self,money): #这里类的方法可能由于程序员的疏忽,写的不是一致的pay,导致后面调用的时候找不到pay
print('支付宝支付了')
class Apppay:
def pay(self,money):
print('苹果支付了')
class Weicht:
def pay(self,money):
print('微信支付了')
def pay(payment,money): # 支付函数,总体负责支付,对应支付的对象和要支付的金额
payment.pay(money)
p=Alipay() #不报错
pay(p,200) #调用执行就会报错,'Alipay' object has no attribute 'pay'
这时候怎么办呢?可以手动抛异常:NotImplementedError来解决开发中遇到的问题
class payment:
def pay(self):
raise NotImplementedError #手动抛异常
class Alipay:
def paying(self, money): # 这里类的方法不是一致的pay,导致后面调用的时候找不到pay
print('支付宝支付了')
def pay(payment, money): # 支付函数,总体负责支付,对应支付的对象和要支付的金额
payment.pay(money) p = Alipay() # 不报错
pay(p, 200) #调用的时候才会报错 'Alipay' object has no attribute 'pay'
也可以借用abc模块来处理这种错误
from abc import abstractmethod, ABCMeta #接口类中定义了一些接口名:Pay,且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
class Payment(metaclass=ABCMeta): #抽象出的共同功能Pay
@abstractmethod
def pay(self,money):pass #这里面的pay 来源于下面类中的方法pay,意思把这个方法规范为统一的标准,另外建一个规范类Payment
class Alipay(Payment):
def paying(self, money): #这里出现paying和我们规范的pay不一样,那么在实例化 Alipay的时候就会报错
print('支付宝支付了')
class Weicht(Payment):
def pay(self,money):
print('微信支付了')
def pay(pay_obj,money):
pay_obj.pay(money)
p=Alipay() #实例化的时候就会报错 Can't instantiate abstract class Alipay with abstract methods pay 之前两个例子都是在执行的时候报错,这里不一样的是实例化就会知道是哪里发生错误了
"""
总结:用abc模块装饰后,在实例化的时候就会报错,那么当我们代码很长的时候,就可以早一点预知错误,所以以后在接口类类似问题中用这个模块
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,
可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
"""
二、接口类多继承
from abc import abstractmethod,ABCMeta
class Walk_animal(meteaclass=ABCMeta):
@abstractmethod
def walk(self):
print('walk')
class Swim_animal(meteaclass=ABCMeta):
@abstractmethod
def swim(self):pass
class Fly_animal(metaclass=ABCMeta)
@abstractmethod
def fly(self):pass
#如果正常一个老虎有跑和跑的方法的话,我们会这么做
class Tiger:
def walk(self):pass
def swim(self):pass
#但是我们使用接口类多继承的话就简单多了,并且规范了相同功能
class Tiger(Walk_animal,Swim_animal):pass
#如果此时再有一个天鹅swan,会飞,走,游泳 那么我们这么做
class Swan(Walk_animal,Swim_animal, Fly_animal):pass
# 这就是接口多继承
接口提取了一群类共同的函数,可以把接口当做一个函数的集合。 然后让子类去实现接口中的函数。 这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。 归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。 比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。 再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样 为何要用接口
为什么需要接口类
三、抽象类
#抽象类
# 抽象类的本质还是类,
# 指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性
"""
1.抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
2.在继承抽象类的过程中,我们应该尽量避免多继承;
3.而在继承接口的时候,我们反而鼓励你来多继承接口
# 一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
# 多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中 """
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
为什么要有抽象类
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的
#一切皆文件
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)
四、扩展:
不管是抽象类还是接口类 : 面向对象的开发规范 所有的接口类和抽象类都不能实例化
java :
java里的所有类的继承都是单继承,所以抽象类完美的解决了单继承需求中的规范问题
但对于多继承的需求,由于java本身语法的不支持,所以创建了接口Interface这个概念来解决多继承的规范问题
python:
python中没有接口类 :
python中自带多继承 所以我们直接用class来实现了接口类
python中支持抽象类 : 一般情况下 单继承 不能实例化
且可以实现python代码
五、注意
"""
1.多继承问题
在继承抽象类的过程中,我们应该尽量避免多继承;
而在继承接口的时候,我们反而鼓励你来多继承接口 2.方法的实现
在抽象类中,我们可以对一些抽象方法做出基础实现;
而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现
"""
python--接口类与抽象类的更多相关文章
- Python——接口类、抽象类
建立一个接口类.抽象类的规范 from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): # 元类 默认的元类 t ...
- [ python ] 接口类和抽象类
接口类 继承有两种用途:1. 继承基类的方法,并且做出自己的改变或者扩展(代码重用)2. 申明某个子类兼容于某基类,定义一个接口类interface,接口类定义了一些接口名且未实现接口的功能,子类继承 ...
- Python 接口类或抽象类 反射
# 抽象类或者接口类,制定规范,统一方法名 # # 抽象类或者接口类,制定规范,统一方法名 from abc import ABCMeta,abstractmethod class Payrole(m ...
- python学习之老男孩python全栈第九期_day025知识点总结——接口类、抽象类、多态、封装
一. 接口类 java:面向对象编程 设计模式 -- 接口类 接口类:python原生不支持 抽象类:python 原生支持的 from abc import abstractclassmethod, ...
- Python面向对象之接口类(抽象类)
Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...
- Python学习日记(二十五) 接口类、抽象类、多态
接口类 继承有两种用途:继承基类的方法,并且做出自己的改变或扩展(代码重用)和声明某个子类兼容于某基类,定义一个接口类interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子 ...
- day 25-1 接口类、抽象类、多态
# 接口类:python 原生不支持# 抽象类:python 原生支持的 接口类 首先我们来看一个支付接口的简单例子 from abc import abstractmethod,ABCMeta #我 ...
- day25:接口类和抽象类
1,接口类和抽象类知识背景:一开始在程序界是没有这些概念的,后来就流行了一种语言叫做JAVA,JAVA是一种典型的纯面向对象的语言,JAVA写的程序都是非常适用于更庞大的项目,很多程序员就总结出了一些 ...
- 资料整理:python接口类
1开发原则(七大原则) 一:开放封闭原则 二:接口隔离原则(将不同接口对象一一展现出来,分别调用各自的接口,完成各自的功能) 三:依赖倒置原则 高级模块不能依赖低级模块,可以依赖抽象 规范的定义: 高 ...
- python编程设计模式之接口类和抽象类
接口类 """ 接口类 是一种编程设计模式,在python原本没有接口类 借用Java思想创建的一种规范设计模式 支持多继承,进行多方面规范 ""&q ...
随机推荐
- span 设置inline-block 写文字的span错位
写一个如下图这样排版 设置几个span为inline-block 中间的span写了文字的span错位了 解决方案 给span添加 vertical-align: top
- python调用tushare获取沪深A股票资金流向数据
接口:moneyflow 描述:获取沪深A股票资金流向数据,分析大单小单成交情况,用于判别资金动向 限量:单次最大提取4000行记录,总量不限制 积分:用户需要至少1500积分才可以调取,基础积分有流 ...
- vue-cli 中多个组件共用一个mt-checklist
// html <div v-if="dataList"> <mt-popup v-model="popupVisible" position ...
- 实现一个EventEmitter类,这个类包含以下方法: on/ once/fire/off
实现一个EventEmitter类,这个类包含以下方法: on(监听事件,该事件可以被触发多次)- once(也是监听事件,但只能被触发一次)- fire(触发指定的事件)- off(移除指定事件的某 ...
- NDK笔记(二)-在Android Studio中使用ndk-build(转)
前面一篇我们接触了CMake,这一篇写写关于ndk-build的使用过程.刚刚用到,想到哪儿写哪儿. 环境背景 Android开发IDE版本:AndroidStudio 2.2以上版本(目前已经升级到 ...
- spring.xml及注解
spring.xml配置文件中配置注解: 开启注解(及自动扫描包中bean): 1:<context:component-scan base-package="com.bzu" ...
- 浅谈JAVA线程
一.线程(Thread) 1.线程 线程:是指程序中的顺序流 多线程:一个程序中的多个顺序流同时执行 (1)线程的状态: 新生 就绪 运行 阻塞 终止 (2)学习多线程: 1)线程的创建 2)线程的状 ...
- leetcood学习笔记-28-KMP*
题目: 第一次提交: class Solution: def strStr(self, haystack: str, needle: str) -> int: if not len(needle ...
- Python与JAVA的异同
--效率: 作为静态语言的JAVA执行效率比动态型语言的Python高 --语法: Python语句更精简. JAVA中的所有变量需要先声明(类型),才能使用,Python不需要声明变量类型 Pyth ...
- PHP ftp_connect() 函数
定义和用法 ftp_connect() 函数打开 FTP 连接. 当连接打开后,您就可以通过服务器来运行 FTP 函数了. 语法 ftp_connect(host,port,timeout) 参数 描 ...