Python: 继承还是组合

15 投票
4 回答
4948 浏览
提问于 2025-04-15 20:04

假设我有一个 class,它使用了一些 dict 的功能。我之前是把一个 dict 对象放在里面,然后从外部访问它,但最近我想到了一个新主意,就是直接继承 dict,然后添加一些我可能需要的属性和方法。这样做好吗?还是说我应该继续使用组合的方式?

4 个回答

3

这两种方法都不错,但我更喜欢继承,因为这样代码会更少(只要代码可读,少一些总是好的)。

Dive into Python 有一个非常相关的例子

在 Python 2.2 及之前的版本,你不能直接从内置类型继承,所以你必须使用组合的方式。

class FileInfo(dict):                  
   "store file metadata"
   def __init__(self, filename=None): 
       self["name"] = filename
  1. 第一个区别是你不需要导入 UserDict 模块,因为 dict 是一个内置的数据类型,随时可以用。第二个区别是你是直接从 dict 继承,而不是从 UserDict.UserDict 继承。
  2. 第三个区别虽然不太明显,但很重要。由于 UserDict 的内部工作方式,你需要手动调用它的 __init__ 方法来正确初始化它的内部数据结构。而 dict 不是这样,它不是一个包装器,不需要明确的初始化
3

你真的需要好好考虑一下你想做的事情的成本和范围。如果你只是想要字典那样的行为,直接从 dict 继承是简单又快速的,但这样做会有一些限制,比如会导致你用这个类创建的对象不能被哈希。

举个例子,如果你需要把对象序列化(也就是用 pickle),同时又想要字典那样的功能,那么显然你不能直接从 dict 继承,这时候你就需要把你想要的功能组合起来,才能实现你的需求。

14

继承这个概念常常被滥用。除非你的类是为了作为一个带有额外功能的通用字典,否则我建议使用组合的方式。

仅仅为了节省调用的时间,通常并不足以选择继承。

来自设计模式书中的一句话:

更倾向于使用对象组合,而不是类继承。

理想情况下,你不应该为了实现重用而创建新的组件。你应该能够通过组合现有的组件来获得所需的所有功能。但实际上,这种情况很少发生,因为可用的组件集合往往不够丰富。通过继承来重用可以更容易地创建新的组件,以便与旧组件组合。因此,继承和对象组合是可以一起工作的。

然而,我们的经验是,设计者往往过度使用继承作为重用的手段,而通过更多依赖对象组合,设计通常会变得更可重用(也更简单)。

完整的内容在这里: http://blog.platinumsolutions.com/node/129

撰写回答