一、抽象类和接口类
继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
归一化设计:不管哪一个类的对象,都调用同一个函数
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # 抽象类或接口类,作为一个规范或约束,metaclass指定一个元类 def pay(self): pass class Alipay(Payment): def pay(self, money): print("使用支付宝支付了%s元" % money) class QQpay(Payment): def pay(self, money): print("使用qq支付了%s元" % money) class Wechatpay(Payment): def pay(self, money): print("使用微信支付了%s元" % money) def pay(s, money): # 归一化设计,不管是哪一个类的对象,都调用同一个函数去完成相似的功能 s.pay(money) a = Alipay() a.pay(100) pay(a, 100)
抽象类和接口类做的事情:建立规范
制定一个类的metaclass是ABCMeta
那么这个类就变成了一个抽象类(接口类)
这个类的主要功能是建立一个规范
抽象类中所有被abstractmethod装饰的方法都必须被继承的子类实现
如果不实现,那么在实例化的阶段将会报错
无论是抽象类和接口类(metaclass=ABCMeta),都不可以被实例化
二、抽象类
什么是抽象类
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
为什么要有抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法
抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。
抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计
在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念。
1.多继承问题
在继承抽象类的过程中,我们应该尽量避免多继承;
而在继承接口的时候,我们反而鼓励你来多继承接口
2.方法的实现
在抽象类中,我们可以对一些抽象方法做出基础实现;
而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现
三、接口隔离
接口:接口提取了一群类共同的函数,可以把接口当做一个函数的集合。
然后让子类去实现接口中的函数。
这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。
归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。
接口类的作用:
在Java中,能够满足接口隔离原则,并且完成多继承的约束
而在python中,满足接口隔离原则,由于python本身支持多继承,所以就不需要接口的概念了
抽象类和接口类:
在python中:
在python中并没有什么不同,都是用来约束子类中的方法的
只要是抽象类和接口类被abstractmethod装饰的方法,都需要被子类实现
需要注意的是,当多个类之间有相同的功能也有不同的功能的时候,应该采用多个接口类来进行分别的约束
在Java中:
抽象类和接口截然不同
抽象类本质还是一个类,是类就必须遵循单继承的规则,所以一个子类如果被抽象类约束,那么它只能被一个父类控制
当多个类之间有相同的功能也有不同的功能的时候,Java只能用接口来解决问题
抽象类:是python中定义类的一种规范,按抽象类中的规范一一实现对应的方法
四、python编程原则
1、开放封闭原则:
开放:对扩展是开放的
封闭:对修改是封闭的
2、依赖倒置原则
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程
3、接口隔离原则:
使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。
五、多态
强类型语言:Java c++ c# # 相同数据类型之间做运算 数据类型必须指定 因此Java需先声明一个父类,利用父类作为数据类型
弱类型语言:shell
介于两者之间:python # 动态强类型语言
多态和鸭子类型
多态 通过继承实现
java 在一个类之下发展出来的多个类的对象都可以作为参数传入一个函数或者方法
在python中不需要刻意实现多态,因为python本身自带多态效果
鸭子类型
不是通过具体的继承关系来约束某些类中必须有哪些方法名
是通过一种约定俗成的概念来保证在多个类中相似的功能叫相同的名字