具体内容见“如何理解UML2.5.1(05篇)”一文。
我的问题是,我在此文中给出的redefines的最新解释是否正确?如不正确,请给出一个正确的解释。
我倒是希望我给出的这个解释不正确,因为其还是与完全没有subsets/redefines标记的区别太少,能应用的场景太少。
欢迎大家积极评论、留言,先感谢了。
感谢大家的回复,受到大家给出的答案的启发,现在我提出一个最新答案,还请大家批评指正。谢谢。
两个关联具有泛化关系的两个先决条件:
一、两个关联在语义上具有泛化关系;
二、两个关联联接两对具有泛化关系的类。
这就导致如果两个关联具有泛化关系,则关联两个端点必须具有subsets/redefines标记。
以“UML2.5.1”中的Figure9.4为例,其右侧的Classifier和ClassifierTemplateParameter之间有两个关联,左边一个关联(Asso1)两端有redefines标记,右边一个关联(Asso2)两端则没有任何标记。
Asso1满足前述两个先决条件,因此Asso1与第三个关联(Asso3)之间具有泛化关系,进而导致Asso1两端都有redefines标记。
Asso2满足第二个先决条件(因为其与Asso1联接的是相同的类),但是不满足第一个先决条件。由于其与其它关联之间没有泛化关系,因此关联两端没有任何标记。
现在也可以解释为什么redefines与没有subsets/redefines标记的效果可以完全相同。原因也不复杂,当关联一端,尤其是两端有redefines标记时,其作用是告诉看图人这是一个泛化关联。也就是说,关联两端都有redefines标记的效果与没有subsets/redefines标记的效果完全相同,但是前者还有一个后者不具有的功能:即其所修饰的关联是一个泛化关联。这个功能在Figure8.4中还不明显,因为泛化和被泛化的关联在同一个图中。但是这个功能在例如前述Figure9.4中就很明显,如果Asso1两端没有任何标记,则很难让看图人知道这是一个泛化关联。而造成这个问题的起因就在于UML2.5.1放弃了之前用在关联之间画继承符号的方式表达关联泛化。
因此现在我又有了一个新问题:
我之前给出的那个解释是不是画蛇添足?
欢迎大家继续讨论,先感谢了。
做个记号~晚点再看
在UML中,标记"redefines"表示子类可以重新定义父类的元素,并覆盖父类的定义。这是一种继承关系,表明子类包含了父类的所有内容,并且可以对父类的元素进行重新定义。
标记"subsets"表示子类继承了父类的一个子集,并不包含所有的父类元素。
常见的例子是,一个子类可能会继承父类的一个属性,并在子类中重新定义这个属性,从而改变属性的值或类型。例如,在一个继承关系中,如果父类有一个名为"color"的属性,并且子类使用"redefines"标记重新定义了这个属性,那么子类就可以改变这个属性的值或类型。
如果使用"subsets"标记,则子类将继承父类的"color"属性,但不能对其进行重新定义。
总的来说,"redefines"标记用于在继承关系中允许子类重新定义父类的元素,而"subsets"标记用于表示子类继承父类的一个子集,但不能对父类的元素进行重新定义。
你给出的解释看起来是正确的。下面是一些补充:
subsets和redefines是UML关联关系中的两种标记,它们的作用是用来表示关联的两端的类型之间的继承关系。
subsets标记表示关联的两端的类型之间是父子关系,即子类继承自父类。在这种情况下,当向关联中添加新的链接时,新的链接的两端的终点对象必须是关联两端类型的子类。
redefines标记表示关联的两端的类型之间是重定义关系,即子类重新定义了父类的某些属性或行为。在这种情况下,当向关联中添加新的链接时,新的链接的两端的终点对象必须是关联两端类型的父类或子类。
如果关联两端都没有subsets或redefines标记,则关联两端的类型没有任何继承关系,在这种情况下,当向关联中添加新的链接时,新的链接的两端的终点对象的类型可以是任意类型。
其实前前后后看了你很多系列的博文,发现你对这一块研究的很透彻,这里作为小白,只提出一些小白式的见解:
首先我是从标记的两个单词上进行理解,一个是subsets,表示分组,子集的意思;另一个是redefines,表示重新定义,重新考虑的意思
从你这篇博文【如何理解UML2.5.1(05篇)】,图表达来看,

A、B是2个subsets,表示2个分组或者2个子集;A1、B1是2个redefines,表示2个重新定义。
用你另外一篇博文的见解去理解【如何理解UML2.5.1(03篇)】:
关联端点具有标识redefines表明这是对被redefines的关联端点的重定义。
此时,有两种情况:如果关联一端由类拥有,则redefines一端的类与被redefines一端的类之间一定有继承关系;
如果关联一端由关联拥有,则redefines一端的关联与被redefines一端的关联之间一定有继承关系。
同时,redefines一端的角色名一定与被redefines一端的角色名相同
(当然实际上不相同也可以,但是一律设置为相同也不会有错误,并且这样还会使类图更加清晰)。
我的理解是包含关系,包含与被包含,包含关系,
例如A1、A2、A3都是A的延续
又同时具备扩展关系,扩展与被扩展,相当于一个新的生命体,类似泛化(父子)关系
当然,这其中用用例图的方式,还可以假设更多的可能,例如实现关系;依赖关系;关联关系:单向关联、双向关联;自关联;聚合;组合等等。
so,回归正解:
subsets分组表示A、B关联的两端是父子关系,即子类继承自父类。存在包含与被包含关系,当向关联中添加新的【生命体】链接时,新的【生命体】链接两端的终点对象必然是关联两端类型的子类。
redefines重定义表示关联的A1、B1两端的类型之间是重定义关系,即子类重新定义了父类的某些属性或行为。存在扩展与被扩展关系,当向关联中添加新的【生命体】链接时,新的【生命体】链接的两端的终点对象必然是关联两端类型的父类。
【个人见解,如有不当,恭请指点】
打不开链接
在UML中,标记redefines表示一个属性或行为覆盖另一个属性或行为,使得它在当前元素的上下文中重新定义。这意味着,在当前元素的继承体系中,可以使用一个属性或行为来覆盖它在父类中定义的同名属性或行为。
举个例子,假设有一个父类A,它有一个行为f(),和一个子类B,它继承了A中的行为f()。如果B中的行为f()使用标记redefines来覆盖A中的行为f(),那么在B的上下文中,行为f()将被重新定义为B中的行为f(),而不是A中的行为f()。
另一方面,标记subsets表示一个属性或行为是另一个属性或行为的子集。这意味着,子集属性或行为的约束条件是父集属性或行为的子集。换句话说,子集属性或行为的值域是父集属性或行为的子集。
举个例子,假设有一个属性P,它的值域为{1, 2, 3, 4},和一个属性Q,它使用标记subsets来表示P的子集。那么Q的值域必须是P的子集,例如{1, 2}或{3}。
可以的
重新定义。
什么
经过进一步的分析,我们可以有如下结论:
结论一:如果添加的链接两端的终点对象的类型与要加入的关联的两端的类型相同,则关联两端都是redefines标记的作用与关联两端没有任何subsets/redefines标记的作用完全相同,这里即是仅向A1和B1的关联中添加链接,而不会向A2和B2的关联中添加链接,因为终点对象没有对应的子类对象;
结论二:如果关联(A1和B1)两端的标记都是subsets,则计算的前进方向是父类方向;
结论三:如果希望A1和B1之间的关联向子类方向前进,则需要满足三个前提条件:
条件一、A1和B1所在关联两端的标记都是redefines;
条件二、A2和B2所在关联两端的标记都是subsets;
条件三、新增的链接两端的终点对象的类型是A1和B1类型的子类。
结论四:如果关联(A1和B1)两端的标记一个是subsets,一个是redefines,则计算保持在原地不动,即仅向A1和B1之间添加链接,而A和B以及A2和B2之间则不添加任何链接;
正如前面结论三所示,这个解释的最大问题在于应用其的门槛太高,因此导致在绝大多数情况下,其所产生的效果与关联两端没有subsets/redefines标记的效果完全相同。
这是你的解释吧
如果添加的链接两端的终点对象的类型与要加入的关联的两端的类型相同,则关联两端都是redefines标记的作用与关联两端没有任何subsets/redefines标记的作用完全相同