消除多重继承
我遇到了一个问题,想知道有没有好的方法来建模这些对象,而不使用多重继承。顺便说一下,我使用的是Python。
学生需要联系信息和学生信息。成年人需要联系信息和账单信息。学生可以是成年学生,这种情况下我需要联系信息、学生信息和账单信息;或者他们可以是小孩,这种情况下我需要联系信息、学生信息和家长信息。
为了让大家更清楚这个系统是怎么用的,我需要能够请求一个所有成年人的列表(这样我会得到成年学生和家长),或者一个所有学生的列表(这样我会得到小学生和成年学生)。
另外,所有这些对象都需要有一个共同的基类。
8 个回答
听起来你其实并不需要多重继承。实际上,你根本不“需要”多重继承。这只是一个问题,看多重继承是否能让事情变得简单(在这里我看不出它能简化什么)。
我会创建一个“人”类,把成年人和学生共有的代码放在里面。然后,你可以有一个“成年人”类,里面包含只有成年人需要的内容,还有一个“孩子”类,里面放只有孩子需要的代码。
我相信很快会有人评论这个问题(如果还没有的话),一个好的面向对象的原则是“更倾向于组合而不是继承”。根据你的描述,听起来你可能违反了单一职责原则,应该把功能拆分成不同的对象。
我还想到,Python支持鸭子类型,这就引出了一个问题:“为什么所有的类都必须有一个共同的基类这么重要呢?”
你所提到的例子是关于角色的。很多人会犯一个错误,把角色用继承的方式来建模,但角色是会变化的。而且,改变一个对象的继承结构(即使在像Python这样的语言中可以做到)其实并不推荐。就像孩子长大成人一样,有些成年人还会成为孩子的父母,同时他们自己也是学生——他们可能会放弃某个角色,但需要保留另一个角色(比如他们的孩子换了学校,但他们自己没有,或者反过来)。
所以,建议你创建一个“人”的类,里面有一些必填的字段和一些可选的字段,而可选的字段可以用来表示角色,这些角色是可以变化的。至于“请求一个列表”(不管是用继承还是其他方式),可以通过实时生成列表来实现(遍历所有对象,检查每个对象是否符合要求),或者维护一个对应于可能要求的列表(或者两种策略结合使用,以应对常见和临时的查询)。在这里,某种数据库可能会很有帮助(而且大多数数据库在没有继承的情况下工作得更好)。