python 处理多重继承

继承有很多用途,而多重继承增加了可选方案和复杂度。使用多重继承 容易得出令人费解和脆弱的设计。我们还没有完整的理论,下面是避免把类图搅乱的一些 建议。

1、把接口继承和实现继承区分开
使用多重继承时,一定要明确一开始为什么创建子类。主要原因可能有:
1,继承接口,创建子类型,实现“是什么”关系 。
2,继承实现,通过重用避免代码重复

其实这两条经常同时出现,不过只要可能,一定要明确意图。通过继承重用代码是实现细节,通常可以换用组合和委托模式。而接口继承则是框架的支柱。

2、 使用抽象基类显式表示接口
现代的 Python 中,如果类的作用是定义接口,应该明确把它定义为抽象基类。Python 3.4 及以上的版本中,我们要创建 abc.ABC 或其他抽象基类的子类

3、 通过混入重用代码
如果一个类的作用是为多个不相关的子类提供方法实现,从而实现重用,但不体现“是什么”关系,应该把那个类明确地定义为混入类(mixin class)。从概念上讲,混入不定义 新类型,只是打包方法,便于重用。混入类绝对不能实例化,而且具体类不能只继承混入类。混入类应该提供某方面的特定行为,只实现少量关系非常紧密的方法。

4、在名称中明确指明混入
因为在 Python 中没有把类声明为混入的正规方式,所以强烈推荐在名称中加入 ...Mixin 后缀。Tkinter 没有采纳这个建议,如果采纳的话,XView 会变成 XViewMixin,Pack 会变成 PackMixin

5、 抽象基类可以作为混入,反过来则不成立
抽象基类可以实现具体方法,因此也可以作为混入使用。不过,抽象基类会定义类型,而混入做不到。此外,抽象基类可以作为其他类的唯一基类,而混入决不能作为唯一的超类,除非继承另一个更具体的混入——真实的代码很少这样做。

抽象基类有个局限是混入没有的:抽象基类中实现的具体方法只能与抽象基类及其超类中 的方法协作。这表明,抽象基类中的具体方法只是一种便利措施,因为这些方法所做的一 切,用户调用抽象基类中的其他方法也能做到。

6.、不要子类化多个具体类
具体类可以没有,或最多只有一个具体超类。也就是说,具体类的超类中除了这一个具体 超类之外,其余的都是抽象基类或混入。例如,在下述代码中,如果 Alpha 是具体类,那 么 Beta 和 Gamma 必须是抽象基类或混入:

class MyConcreteClass(Alpha, Beta, Gamma):    
	 """这是一个具体类,可以实例化。"""    
	  # ……更多代码……

7、 为用户提供聚合类
如果抽象基类或混入的组合对客户代码非常有用,那就提供一个类,使用易于理解的方式 把它们结合起来。Grady Booch 把这种类称为聚合类(aggregate class)。(如果一个类的结构主要继承自混入,自身没有添加结构或行为,那么这样的类称为聚合类)

例如,下面是 tkinter.Widget 类的完整代码:

class Widget(BaseWidget, Pack, Place, Grid): 
	"""Internal class. 
    Base class for a widget which can be positioned with the geometry managers Pack, 
    Place or Grid."""
    pass

Widget 类的定义体是空的,但是这个类提供了有用的服务:把四个超类结合在一起,这样 需要创建新小组件的用户无需记住全部混入,也不用担心声明 class 语句时有没有遵守特 定的顺序。Django 中的 ListView 类是更好的例子。

8、 “优先使用对象组合,而不是类继承”
这句话引自《设计模式:可复用面向对象软件的基础》一书,这是我能提供的最佳建议。 熟悉继承之后,就太容易过度使用它了。出于对秩序的诉求,我们喜欢按整洁的层次结构 放置物品,程序员更是乐此不疲。

然而,优先使用组合能让设计更灵活。例如,对 tkinter.Widget 类来说,它可以不从全部 几何管理器中继承方法,而是在小组件实例中维护一个几何管理器引用,然后通过它调用 方法。毕竟,小组件“不是”几何管理器,但是可以通过委托使用相关的服务。这样,我 们可以放心添加新的几何管理器,不必担心会触动小组件类的层次结构,也不必担心名称 冲突。即便是单继承,这个原则也能提升灵活性,因为子类化是一种紧耦合,而且较高的 继承树容易倒。

组合和委托可以代替混入,把行为提供给不同的类,但是不能取代接口继承去定义类型层 次结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值