Python3学习(25)--多继承之mix-in("混入")技术

前面,我们学习过OOP的继承,知道子类可以继承父类的特性,可以拿来用,也可以改变父类的特性变为已有,当然,我们只是学习了一种继承关系,今天,我们要重新认识一下Python的继承之


多继承


静态语言中,C++支持多继承,一个子类可以拥有多个父类,但是对于Java来说,就不行了,只能实现单继承,Java可以巧妙的利用实现多个接口(interface),内部类等来实现这种"多继承"。



动态语言中,Python是没有接口的,本身也不提供抽象类一说,为什么要像Java一样,当一个类实现一个接口的时候,它必须实现接口中声明的所有方法,否则会出错。我们的Python才不会这么设计,一方面是因为它支持多重继承,另一方面,是因为Python活泼,,我们可以设计一个"伪接口"如下:


class interface():

            pass


如果是Java的话,interface中你需要事先声明好方法体,不然,你让别人实现你接口什么呢?


但是我们的Python,可以动态给interface绑定方法甚至变量


import types


def func(*args,**others): #定义一个方法

          #do something


interface.my_func = types.MethodType(func,interface)  #给接口绑定一个接口方法,方法显然已被实现

i = interface()    #接口实例(其实就是类,这里我们模仿接口)

i.my_func(*args,**others)  #类的属性,可以被所有属于类的实例访问,因此这里我们用接口实例调用方法



看了上面的伪代码后,我们是不是觉得,接口对于Python来说意义不大?来来,我们围观一下执行结果:





不止一种?


今天虽说是讲多继承的,但是我们不得不说下,接口这个事,既然语言又不止Python一种,我们何不多花点时间多学一点呢?



抽象类


Python本身不提供抽象类,但是,我们可以借助abc模块,进行抽象类的模拟和实现(等同于Java接口的定义)


我们看下demo:


#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-

from  abc import ABCMeta,abstractmethod #abc模块提供抽象类机制 

class interface(metaclass = ABCMeta): #指定当前类是一个抽象类
    @abstractmethod  #指定抽象方法
    def A(self):
        pass
    @abstractmethod
    def B(self):
        pass
     
i = interface()



我们猜测一下,这个抽象类能不能被实例化,也就是上述的最后一行代码可行否?我们看下,IDE给我们的答案是什么:




上述的意思,大概是,我们必须先实现抽象类interface的两个方法A和B,是必须! 下面我们定义一个类,继承这个inteface,并实现抽象方法A和B:


#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-

from  abc import ABCMeta,abstractmethod #abc模块提供抽象类机制 

class interface(metaclass = ABCMeta): #指定当前类是一个抽象类
    @abstractmethod  #指定抽象方法
    def A(self):
        pass
    @abstractmethod
    def B(self):
        pass
     
class Implement(interface):
    def A(self):
        print("必须实现抽象方法A")
    def B(self):
        print("必须实现抽象方法B")
        
impl = Implement()
impl.A()
impl.B()

如果我们在实现类Implement中没有实现方法B,会提示如下:




但是我们全部实现后,就会很顺畅的输出结果如下:




利用Python的abc模块,我们可以将抽象机制应用在接口上,从而"实现接口"



回到本篇的内容,我们说下多继承


我们知道青蛙Frog,是两栖动物,既可以在陆地上跑,也可以在水里游,如果跑和游是两个更加抽象的类,需要被具体的话,那么仅凭单继承的话,青蛙只能继承一种父类行为,要么跑,要么游,假设,我们让青蛙先继承跑,然后,在这种跑的行为上,为青蛙"混入"额外的功能游,那么就必须让青蛙再继承游才行,这就必须要用到多继承了,这种设计模式在Python中称之为MixIn,中文我们就称"混入"吧。


针对上面描述的,我们设计我们的demo如下:


#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-

class Runnable():
    def run(self):
        print("I can run...")
        
class Swimable():
    def swim(self):
        print("I can swim...")        

class Frog(Runnable,Swimable):
    pass

print(Frog.__bases__)


我们利用类的属性__bases__打印出,当前类所继承的父类有哪些:




当然,如果我们的类,没有显示指明继承的父类,默认都是object:




我们看下值,不难发现,类的属性__bases__的值是一个tuple元组


其实,多继承很好理解,我们看下,青蛙王子,现在是不是既可以跑又可以游了:





so,多继承又扯了这么多,是时候该结束本篇的内容了,下一篇,我们再继续............


  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值