我想知道如何在python中的 UML术语中实现组合和聚合。
如果我理解:
class B:
pass
class A(object):
def __init__(self):
self.B = B
在其他语言中,我看到这个实现为指向B的指针。我猜这里self.B
是python中的指针。
class A(object):
def __init__(self, B):
self.B = B
是不是?
答案 0 :(得分:25)
If I understand correctly,聚合与组合是关于对象对其成员的责任(例如,如果删除实例,是否也删除其成员?)。
主要是,它将在很大程度上取决于实施。例如,要创建一个接收类B(聚合)实例的类A,您可以编写以下内容:
class B(object): pass
class A(object):
def __init__(self, b):
self.b = b
b = B()
a = A(b)
但是作为一个提醒点,Python没有任何内置功能可以阻止你传入别的内容,例如:
a = A("string") # still valid
如果您想在A(组合)的构造函数中创建B的实例,您可以编写以下内容:
class A(object):
def __init__(self):
self.b = B()
或者,您可以将类注入构造函数,然后创建一个实例,如下所示:
class A(object):
def __init__(self, B):
self.b = B()
顺便说一下,至少在你的第一个例子中,可能是第二个例子,你将B设置为B的类定义,而不是它的实例:
class A(object):
def __init__(self, B):
self.B = B
>>> a = A()
>>> a.B # class definition
<class __main__.B at 0x028586C0>
>>> a.B() # which you can make instances of
<__main__.B instance at 0x02860990>
所以,你最终会得到一个指向B类定义的A实例,我很确定这不是你所追求的。虽然,这在其他语言中通常要难得多,所以我理解这是否是混淆点之一。
答案 1 :(得分:12)
组合和聚合是Association的特殊形式。关联是两个没有任何规则的类之间的关系。
<强>组合物强>
在复合中,其中一个类由一个或多个其他类的实例组成。 换句话说,一个类是容器,其他类是内容,如果删除容器对象,那么它的所有内容对象也会被删除。
现在让我们看一下Python 3.5中的组合示例。类Employee是容器,类Salary是内容。
class Salary:
def __init__(self,pay):
self.pay=pay
def get_total(self):
return (self.pay*12)
class Employee:
def __init__(self,pay,bonus):
self.pay=pay
self.bonus=bonus
self.obj_salary=Salary(self.pay)
def annual_salary(self):
return "Total: " + str(self.obj_salary.get_total()+self.bonus)
obj_emp=Employee(100,10)
print (obj_emp.annual_salary())
<强>聚合强>
聚合是一周形式的构图。如果删除容器对象,则对象可以不带容器对象。
现在让我们看一下Python 3.5中的聚合示例。 Class Employee再次是容器,而类Salary是内容。
class Salary:
def __init__(self,pay):
self.pay=pay
def get_total(self):
return (self.pay*12)
class Employee:
def __init__(self,pay,bonus):
self.pay=pay
self.bonus=bonus
def annual_salary(self):
return "Total: " + str(self.pay.get_total()+self.bonus)
obj_sal=Salary(100)
obj_emp=Employee(obj_sal,10)
print (obj_emp.annual_salary())
答案 2 :(得分:2)
# Aggregation is NOT exclusive
class BaseChapter:
'''
We can use this BaseChapter in any book, like in OpenBook.
'''
def __init__(self, name):
self.name = name
self.subject = None
self.content = None
return
class OpenBook:
def __init__(self, isbn):
self.isbn = isbn
self.chapters = list()
def add_chapter(self, obj):
# This constrain dont have correlation with composition/aggregation
if isinstance(obj, BaseChapter):
self.chapters.append(obj)
else:
raise TypeError('ChapterError')
# .. but Composition is Exclusive
# Example:
class MyBook:
class MyChapter:
'''
This MyChapter can be used only by MyBook
'''
def __init__(self, name, subject):
self.name = name
self.subject = subject
self.title = None
self.content = None
self.techincal_refs = list()
return
def __init__(self, isbn):
self.isbn = isbn
self.chapters = list()
def add_chapter(self, obj):
# This constrain dont have correlation with composition/aggregation
# what is important here is MyChapter can be used only by MyBook
# a outside object cant create a instance of MyChapter
if isinstance(obj, self.MyChapter):
self.chapters.append(obj)
else:
raise TypeError('ChapterError')
..是的,我们可以做得更好,比如
class MyBook:
class MyChapter(BaseChapter):
'''
This MyChapter can be used only by MyBook,
but now is based in BaseChapter.
But you knhow, python dont create problems if you still want
create a instance of MyChapter in other 'Books'.
But when you see this code you will think, This class is exclusive
to MyBook.
'''
def __init__(self, name):
super().__init__(name)
self.subject = None
self.title = None
self.content = None
self.techincal_refs = list()
return
def __init__(self, nib):
self.nib = nib
self.chapters = list()
def add_chapter(self, obj):
# This constrain dont have correlation with composition/agregation
# what is important here is MyChapter can be used only by MyBook
if isinstance(obj, self.MyChapter):
self.chapters.append(obj)
else:
raise TypeError('ChapterError')