6.6 类的约束
- 首先,你要清楚,约束是对类的约束,什么叫抽象类?从小到大的过程叫做抽象
- 接口类:(在抽象类的基础上)在python中,默认是没有接口类的,接口类不能被实例化(如果实例化会报错),接口类中的方法不能被实现
- 例子:
-
#正常调用 class Applepay: def pay(self,money): print('apple pay 支付了%s'%money) class Alipay: def pay(self,money): print('支付宝 支付了%s'%money) def payment(pay_obj,money):#实例化另外一种调用,这个方法让实例化的时候按照pyment调用就像下面的payment(apple1,200) pay_obj.pay(money) apple1=Applepay() Payment(apple1,200)
- 有时候写的时候会把方法写错,自己定义一个主动报错;接口初成:手动报异常:NotImplementedError来解决开发中遇到的问题
- 例子:
-
class Payment: def pay(self): raise NotImplementedError#主动让程序报错 class Wechatpay(Payment):#微信支付 def pay(self,money): print('微信支付了%s元'%money) class QQchatpay(Payment):#QQ支付 def fuqian(self,money): print('QQ支付了%s元') p=Wechatpay() p.pay(200)#不报错 q=QQchatpay()#不报错 q.pay()#报错,查询子类没有该方法,则查找父类,执行父类的方法,然后报错
- 借用abc模块来实现接口;接口类(就是为了提供标准,约束后面的子类)
- 例子:
-
# 3.借用abc模块来实现接口 #接口类(就是为了提供标准,约束后面的子类) from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self,money): pass class Wechatpay(Payment): def fuqian(self,money): '''实现了pay的功能,但是方法名字不一样''' print('微信支付了%s元'%money) class Alipay: def pay(self,money): print('支付宝 支付了%s' %money) # p = Wechatpay() #报错了(因为上面定义了一个接口类,接口类里面 # 定义了一个pay方法,而在下面的Wechatpay方法里没有pay方法,不能 # 调用,在接口类里面约束一下,接口类里的pay方法里面不能写其他,直接pass) a = Alipay() a.pay(200) p = Payment() #接口类不能被实例化 #借用abc模块来实现接口
- 为何要使用接口:接口提取了一群类共同的函数,可以把接口当做一个函数的集合。
然后让子类去实现接口中的函数。这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。
归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样
- 继承的第二种含义非常重要,它又叫做接口继承
- 接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
- 抽象类:在python中,默认是有的,父类的方法,子类必须实现,抽象类(父类)的方法可以被实现
- 总结:约束. 其实就是?类对?类进?约束. ?类必须要写xxx?法. 在python中约束的?式和?法有两种:
- 使?抽象类和抽象?法, 由于该?案来源是java和c#. 所以使?频率还是很少的
- 使??为抛出异常的?案. 并且尽量抛出的是NotImplementError. 这样比较专业, ?且错误比较明确.(推荐)
6.6 super()深入了解
-
class A: def f1(self): print('in A f1') def f2(self): print('in A f2') class Foo(A): def f1(self): super().f2() print('in A Foo') obj = Foo()#实例化对象obj 将obj对象地址赋值给object init方法中self中 obj.f1()#调用子类中的f1方法 遇到super 执行父类中的f2方法 执行完之后继续执行子类f1方法 #结果为:'in A f2' 'in A Foo'
-
class A: def f1(self): print('in A') class Foo(A): def f1(self): super(Foo,self).f1()#2 按照mro算法 执行bar类 print('in Foo')#4 输出 class Bar(A): def f1(self): print('in Bar')#3输出 class Info(Foo,Bar): def f1(self): super(Info,self).f1()#1 执行父类 Foo print('in Info f1')#5输出 obj = Info()#实例化对象obj,基于Info创建一个对象内存地址赋值给obj obj.f1()#执行f1方法 针对多继承 继承顺序采用 mro(c3)算法,先执行Foo print(Info.mro)# [<class '__main__.Info'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <class '__main__.A'>, <class 'object'>] #结果为:'in Bar''in Foo''in Info f1'
-
class A: def f1(self): print('in A') class Foo(A): def f1(self): super().f1() print('in Foo') class Bar(A): def f1(self):#3 print('in Bar')#4 输出 class Info(Foo,Bar): def f1(self):#1 super(Foo,self).f1()#2 多继承按照c3算法 Foo下一个是bar 执行bar类 print('in Info f1')#5 输出 obj = Info()#对象实例化,obj对象地址赋值给object类中init 方法中self参数 obj.f1()#执行f1函数 现在子类查找(Info) #结果为 'in Bar' 'in Info f1'
原文地址:https://www.cnblogs.com/zhangdadayou/p/11415357.html
时间: 2024-11-05 11:42:35