我在Stackoverflow上看到很多文章,用例子解释了这些关系之间的区别:关联、聚合、组合和继承。然而,我更具体地混淆了每种方法的利弊,以及哪种方法对手头的任务最有效。这是我一直没有找到一个很好的答案。
为了与论坛的指导原则保持一致,我不想问为什么人们个人更喜欢使用继承而不是组合。我对每种方法的任何客观优点/缺点都特别感兴趣,尽管听起来可能很强。一、 一种方法是否比另一种方法创建了更可读的代码,或者它是否具有更好的运行时效率等等
理想情况下,如果有人能给我一些现实世界的例子,说明这些方法可能成功或失败,以及原因,那将对发展我和我希望的其他人的知识非常有用。
为了确保有一个坚实的基础,我在Python 2中包含了每个关系的示例。如果我对这些关系的理解实际上不正确的话,希望这样可以避免混淆。
关联性
类B与类a有一周的关联关系,因为它在addAllNums方法中使用来自a的特定属性。然而,这就是这种关系的程度。
class A(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def addNums():
self.b + self.c
class B(object):
def __init__(self, d, e):
self.d = d
self.e = e
def addAllNums(self, Ab, Ac):
x = self.d + self.e + Ab + Ac
return x
ting = A("yo", 2, 6)
ling = B(5, 9)
print ling.addAllNums(ting.b, ting.c)
聚合
类B与类A形成聚合关系,因为它在初始化时引用独立的A对象作为其属性之一。当B对象依赖于a时,在B被破坏的情况下,a将继续存在,因为它独立于B
class A(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def addNums():
self.b + self.c
class B(object):
def __init__(self, d, e, A):
self.d = d
self.e = e
self.A = A
def addAllNums(self):
x = self.d + self.e + self.A.b + self.A.c
return x
ting = A("yo", 2, 6)
ling = B(5, 9, ting)
print ling.addAllNums()
组成
不过,与聚合非常类似,B实际上不是引用独立对象,而是将其自身构造函数中的A实例初始化为属性。如果B对象被销毁,那么A对象也会被销毁。这就是为什么构图是如此强烈的关系。
class A(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def addNums():
self.b + self.c
class B(object):
def __init__(self, d, e):
self.d = d
self.e = e
self.A = A("yo", 2, 6)
def addAllNums(self):
x = self.d + self.e + self.A.b + self.A.c
return x
ling = B(5, 9)
print ling.addAllNums()
我决定不包括继承的例子,因为我对它非常满意,我觉得它的包含可能会使问题的重点偏离正切点。
不管怎样,以上例子和继承(相互比较)的优缺点是什么。
谢谢。
我个人的意见是,你应该首先考虑如何以帮助你解决具体现实世界问题的方式来模拟现实世界的数据。把事情分配给类,描述类和/或实例之间的关系,描述事情的属性,等等,都是最困难的部分:正确处理这个问题,代码中的模式(无论是继承、聚合、子类化等等)变得容易。例如:
正方形和长方形之间的关系是什么? 可逆矩阵是方阵的一个子类吗? 死牛是哺乳动物吗? 学生是人的一个子类吗?老师是一个亚类吗?助教呢?
根据wikipedia的经验法则是,关系随着时间的推移而软化,或者随着概念模型细节的增加而软化,即组合变为聚合,聚合变为关联,例如,引擎最初可能是汽车的组合,但随着功能的添加,引擎可以从一辆车转移到另一辆车,使之成为一个集合。
所以为了回答你关于每种方法的利弊的问题,它更多的是一个你正在建模的关系的问题,类似于我是否应该将一个名称存储为一个字符串或一个数字的问题
相关问题 更多 >
编程相关推荐