UML类图中的关系是如何继承的?

3
我想知道在UML(或者说一般情况下)中,关联、依赖和其他关系是如何继承的。 比如,在这样的情况下:
  ┌──────────┐                                        ┌──────────┐
  │  ClassA  │                                        │  ClassB  │
  ├──────────┤                                        ├──────────┤
  │          │─────────"One kind of relation"────────>│          │
  ├──────────┤                                        ├──────────┤
  │          │                                        │          │
  └──────────┘                                        └──────────┘
        ^
       /┬\
        │
        │
        │
        │
  ┌─────┴────┐
  │  ClassC  │
  ├──────────┤
  │          │
  ├──────────┤
  │          │
  └──────────┘

注意:
  • ClassA-ClassC之间存在泛化关系,箭头应该是实线
  • ClassA-ClassB之间有[依赖、关联、聚合、组合]中的一种关系
  • Unicode很酷,但用编辑器字体看起来更好 :)

我的问题是,这些关系如何继承?例如,当ClassA依赖于ClassB时,ClassC会依赖于ClassB吗?等等。

谢谢。

3个回答

4
简单的回答是肯定的(对于大多数实际目的来说,你不需要深入了解)。但问题比看起来更加复杂。引用《统一建模语言参考手册第二版》所说:“generalization”和“inheritance”这两个词常常被混用,但实际上它们是两个相关但不同的概念。Generalization是建模元素之间的分类关系,它描述了一个元素是什么。Inheritance是一种机制,用于将共享增量描述组合成一个元素的完整描述。在大多数面向对象的系统中,继承基于泛化,但继承也可以基于其他概念,例如Self语言的委托指针。将继承机制基于泛化关系使得因式分解和描述共享以及多态行为成为可能。这是大多数面向对象语言和UML采取的方法。但请记住,还有其他方法可以采用,并且某些编程语言正在使用这些方法。
我记得在2003年听过一次非常长的讲座,讲述了generalization和inheritance之间的区别。简而言之,这两个概念属于软件设计的不同层次,或者引用Martin Fowler在《UML精简教程第三版》中所说的“建模的各种视角”:
“从概念上讲,我们可以说如果Corporate Customer的所有实例也是Customer的实例,则Corporate Customer是Customer的一个子类型。然后Corporate Customer是一种特殊类型的Customer。”
generalization的概念属于概念、设计层次。
但继承是属于实现视角的概念:
“在软件视角下,显然的解释是继承:Corporate Customer是Customer的一个子类。在主流面向对象语言中,子类继承了超类的所有特征,并可以覆盖任何超类方法。”
我记得有一个例子,它能很好地解释generalization和inheritance之间的区别:
正方形是矩形。这来自它们在数学中的定义:
矩形是四个直角的四边形。
正方形是四条边和角度相等的多边形。
在设计层次上,正方形和矩形之间存在泛化关系。
但在实现层次上,事情有所不同:
矩形可以由两个尺寸来定义:宽度和高度。
正方形可以由单个尺寸来定义,因为所有的边都是相等的。
在Square类中继承Rectangle类的宽度和高度将会是适得其反的,这需要额外的约束条件来确保将相同的值提供给宽度的setter和高度的setter。

这是一个(有点激进,我承认)情况,您不会将一般化关系翻译为在实现层次上使用继承。

那时候真是美好的日子。


1

由于继承是“is-a”(无意冒犯)的关系,所以您可以将其理解为“ClassC是一个ClassA,它知道一个ClassB”,因此:

例如,当ClassA依赖于ClassB时,ClassC是否也依赖于ClassB?

-- 是的 :)


所有关系都是这样吗? - Tamás Szelei

1
你不是在问UML问题,而是在问一个更一般性的问题。
继承的意思是什么?
ClassC是ClassA的子类。在所有实现继承的编程语言中,ClassC将拥有ClassA的所有特性。
在不支持继承的语言中,您必须通过确保ClassA的所有特性也是ClassC的一部分来营造适当继承的假象。
这就是继承的定义。永远如此。即使在UML图中也是如此。

谢谢。我不知道为什么一开始没想到……现在很明显了。 - Tamás Szelei
我认为答案并不那么明显;继承与泛化有关但并非完全相同。请参见我的回答(评论框太小,无法引用UML参考手册中相关的引文)。 - Eric Bréchemier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接