【问题标题】:Composition vs. Inheritance组合与继承
【发布时间】:2020-06-05 06:25:42
【问题描述】:

对于一个UML类图,如果一个类A与另一个类B有组合关系,它的工作方式和继承一样吗?我知道A类没有B类就不能存在,但是A类继承了B类的属性和方法吗?

【问题讨论】:

    标签: oop inheritance uml composition class-diagram


    【解决方案1】:

    组合优于继承

    在 OO 设计中,一个常见的建议是首选composition over inheritance。这可能会误导人们认为这两个不同的概念之间存在关系:

    • 继承是关于类之间的关系。
    • 组合是关于类对象之间的关系。

    更具有误导性:一般 OO 文献中使用的“组合”通常对应于 simple UML association,不应理解为与 UML“组合”一样具有限制性。

    继承就是泛化和特化

    如果类D继承自B,则表示Dspecialises a more general conceptB

    • 具有B的所有属性和操作(图中无需重复),
    • 它可以具有与B 无关的其他属性和操作,并且
    • 它可以以不同的方式执行B的一些操作。
    • D 类的任何对象在其整个生命周期内也是B 类的对象。这就是我们说“”关系的原因。

    朴素的例子(只是为了说明):

    组合是关于非常不同类的对象的关联

    如果B 类“组合”(具有composition association 和)C,则意味着B 对象可以在其生命周期内与不同的C 对象相关联。 Anf 类 C 的对象:

    • 始终属于拥有它的B 对象。这就是为什么我们有时会说“”的关系;
    • 将无法在其拥有的 B 对象中存活。

    警告:UML 组合是关于独占所有权的。在 OO 文献中,术语“组合”通常是指没有任何所有权甚至排他性的较弱关联。

    朴素的例子(只是为了说明):

    【讨论】:

    • 即使您的回答质量很好,我也很少评论。发动机和油井的组成确实不是一个好的选择,我们知道所有的汽车都会被毁坏,而它的某些部分包括发动机/车轮在内仍然存在。还有越来越多的混合动力汽车有多个引擎,包括电动,所以多重性 1 是旧时尚 ^^,然后你可以添加 HybridCar 继承 ElectricalCarGazolineCar。最后我知道它们是汽车,包括有 3 个轮子的旧车(第五个可能是替换 4 个中的一个)。
    • 我确切地说我不 DV 你的答案(也不是另一个),我说以防以后发生,至于包括我在内的其他两个答案(即使我想我知道谁为我做了。 ..)
    • @bruno 感谢您的评论。我应该警告说这些都是“幼稚的例子”。 ,因为我不会在现实生活中对电动汽车使用继承,因为我宁愿使用复合模式或实体组件系统。顺便说一句,既然您是专家:UML 是否在其语义上解决了前一个组件的情况?假设我有 5 个轮子,将它们移除(因为我的 4..5 一个接一个)以将它们添加到另一辆车,然后将新轮子添加到我的车:这不是有效的吗?
    • 这是一个很好的评论,对于发动机和车轮来说,较低的多重性必须为 0 以允许删除其中的一些,例如汽车仍然是一辆汽车,甚至因为没有车轮而无法运行^^ 所以先验引擎的正确多重性是“0..*”或其快捷方式“*”而不限制最大数量,而对于车轮“0..5”假设最大可能为 5。在可以添加关于能够运行的发动机/车轮数量的限制之后
    • 这就是我们回到爱因斯坦的地方:尽可能简单,但并不简单。可以成为长期讨论的东西:-)
    【解决方案2】:

    继承和组合是两个不同的概念。如果它们相同,则不需要使用不同的符号。

    • 组合是关于对象的生命周期的。组合元素将在所有者被销毁的那一刻被销毁。但是每个实例都可以(并且可能会)与组成对象完全不同。众所周知的例子是一辆汽车:当你粉碎一辆汽车时,它的组合轮子也会被粉碎。只有事先将它们分离,它们才能继续存在。

    • 继承意味着实例将在其父类中定义自己的操作和属性。这适用于每个单独的实例。没有很好的真实世界继承示例(基因的工作方式不同,继承的资产在这里也无济于事)。

    【讨论】:

    • 感谢您的解释
    • 请考虑在 Christophe 的回答中打上“正确”的勾号,因为它比我的详细得多。 (他似乎比我有更多的时间;-)
    • 完成!抱歉更改晚了。
    【解决方案3】:

    如果一个类 A 与另一个类 B 有组合关系

    假设您的意思是 A <*>--- BA <*>---> B 而不是相反的(B <*>--- AB <*>---> A),因为这在您的问题中不是很清楚。

    没有b类就不能存在A类

    这不是关于,而是关于这些类的实例,并且B可以有独立于该组合的实例,因此有限的生命并不适用于所有 B 的实例。

    它像继承一样工作吗? A类是否继承了B类的属性和方法?

    没有。

    A继承B的意思是A 是一个 B,这绝对是不是A <*>--- BA <*>---> B 或相反的情况。

    那么独立于操作的可见性,您不能将 A 的操作应用于 B 的实例,也不能反过来,当然,如果您也有继承比作曲还要多。

    关于 B 的属性取决于组合的实现方式,它们可能是 A 的相应实例的一部分,例如C++ 不使用组合的指针。但是无论如何这并不意味着 B 的这些属性是 A 的属性,要访问它们需要首先访问 B 的实例尽管组合,并且还假设 A 的实例有权直接访问 B 的这些属性,因此它们通常是 public

    请注意,您也可以拥有A<*>--->B<*>--->A 等,幸运的是,这确实意味着 A 继承了 B 并且 B 继承了 A em>这是不可能的

    【讨论】:

    • 感谢您的解释
    猜你喜欢
    • 2011-05-20
    • 2014-01-17
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2016-01-05
    • 2014-08-08
    相关资源
    最近更新 更多