前言
redis系列先鸽一次。
最近厂里招人,帮着面了一部分后端候选人。当面试者表示熟悉python的时候,有一个考察角度是从mixin设计模式开场,视程度逐步深入到py中经典类与新式类、多重继承、最后是C3算法的一些讨论。心痒梳理一下,只是泛泛的谈一下心得,欢迎各位大佬批评指正,共同学习。
interface
interface 是java 里较为基础的概念。面向接口编程也是老生常谈了。java中只支持单继承。多重继承会带来一些问题,这个后面谈。所以当一个java的类需要有其他抽象出来的一些特性时,可以实现多个接口,近似达到多继承的效果。
但接口中只是一些抽象方法,具体的实现由实现接口的类去自行完成。可以避免对实现接口这个类的一些侵入。在java8之后虽然接口允许使用默认实现,但它初衷是面向扩展时,可以不强制要求现有其他类跟着一起修改。
抽象基类与mixin
python里是没有interface这个东西的。python支持多继承。可以把抽象基类当作interface来使用。这其实是一种团队风格。
mixin其实也是人为规定的一种设计模式。它原则上和接口的思想并不太一样,mixin是一种工具类,被多继承在类的后面,完成一些功能上的重用。在mixin里面封装了一些已经实现好了的,在项目内部里的一些通用方法,实际侵入到命名空间里。
当然,这个有对命名空间的侵入,以及实际上并不是一个确切的 is-a关系,确切的来说不如组合的模式。但组合的话会持有一个对应的对象,无论是内存考虑还是其他的一些考虑,需要根据实际的业务情形来单独判断。
多重继承与菱形继承问题
实际上py里的多重继承也经历了若干次的迭代与更新,坑还不少。其实多重继承早年在C++中就臭名昭著了,估计java当年设计的时候只支持单继承,就是借鉴了C++的前车之鉴(笑)。C++里面面对菱形继承,实际上有个虚继承来解决最基层的类被实例化多次的问题。
菱形继承
比如 类Q, 同时有WY两个父类, WY有共同的父类K,这种情形就是菱形继承。py里面没有一个父类被实例化多次的情形,但是有方法的解析顺序问题。
方法解析顺序(method resolution order):指的是调用方法时的解析顺序。举个栗子,类Q的实例q中有个 x方法。调用q.x()的时候,假如q中没有这个方法,很自然的就是去父类中去搜索。这个搜索顺序据说方法解析顺序。
一个类实际的解析顺序可以调用它的mro()方法去看。
在经典类时期,是深搜。即 Q -> W -> K 搜索完了,才会去搜索 Q-> Y -> K 这个分支。
在新式类时期,是广搜。即 Q->W->Y->K 的顺序。广搜其实更符合实际应用的情形。这里面有个著名的C3算法。
py3以后只有新式类了,经典类变成了历史的尘埃。
C3算法
曾在网上看过一篇博客C3算法讲的比较易懂,其实核心算法就是魔改过的拓扑排序。
微信公众号里有一些限制:
文章里如果有引用的内容就不能声明原创
个人号每天只能推送一篇推文
所以会在明天(本周日)加推一篇,转载讲解c3算法的博客。
![53da3eadedee2002f85e3c92a2868951.png](https://img-blog.csdnimg.cn/img_convert/53da3eadedee2002f85e3c92a2868951.png)
微信号|xiaoxingblog
欢迎关注小邢的技术博客!