【问题标题】:In an UML diagram, when should a class be abstract?在 UML 图中,类什么时候应该是抽象的?
【发布时间】:2011-02-05 12:46:25
【问题描述】:

在 UML 图中,类什么时候应该是抽象的?就在我们想要阻止实例化的时候?

编辑:一个抽象类能否完全实现一个方法(当方法只依赖于该抽象类的属性时)?

【问题讨论】:

    标签: abstract-class uml


    【解决方案1】:

    防止实例化是一个实现问题,因此如果您正在考虑 Java、C# 等方面的问题,这是一个很好的理由。

    然而,在建模的层面上,如果有多个子类,你会想要使一个类抽象,并且 没有意义 一个对象是超类型但不属于任何一个子类型。

    所以,基本上你不会阻止类的实例化,因为子类的任何实例也是抽象超类的实例。在这种情况下,您正在做的是阻止超类的实例化单独,即强制使用其中一种子类型。

    回答编辑:是的!

    【讨论】:

    • +1 对于子类型和超类型的评论 - 结果似乎是一个学术问题。
    • @amelvin:不明白它的学术性吗? @Goran 是对的。如果超类标记为抽象,那么任何对象都不能单独作为超类型的实例——它也必须是子类型的实例。这是一个重要的区别。
    • @sfinnie 公平点;我的意思是学术,因为我认为这是一个学术边缘案例,而不是现实世界的问题。 OP 在另一条评论中说他的抽象类没有方法,所以它是一个没有实现的抽象类,接口肯定更适合现实世界的例子吗?
    • @sfinnie 再说一遍,如果一个类有一些静态成员,那么它有充分的理由是抽象的 - stackoverflow.com/questions/4901364/…
    • @amelvin, @sfinnie:确实,在实际使用中没有多大意义。我见过没有方法的接口被称为标记接口,它们用于在将注释添加到语言之前向 Java 中的实现类添加额外的信息(我知道它是特定于语言的,但可能就是这种情况)。如果一个类只有静态方法,比如实用程序类,那么我想扩展它是没有意义的。另一方面,如果成员只是常量,那么接口仍然可以完成这项工作。
    【解决方案2】:

    如果一个类有一个或多个抽象操作,那么它就是抽象的。

    在UML中用斜体或{abstract}表示摘要。

    下图(在 Martin Fowler 我的 UML Distilled 第三版书的第 70 页)显示了如何以及为什么要表示摘要:

    【讨论】:

    • 你的第一句话是错误的。反之亦然 - 拥有抽象方法的前提是封闭类是抽象的。你可能有一个包含所有具体方法的抽象类,如果这样定义它仍然是抽象的。
    • @Goran 抱歉,第一句话直接引用自 Martin Fowler 的书 UML Distilled Third Edition,p69,倒数第三段。这个问题是关于 UML,而不是专门的 OOP——一些编程语言允许一个具有所有具体方法的抽象类——有些可能不允许。在 UML 术语中,抽象类通常是具有一个或多个抽象方法的类 - 而不是相反。
    • Goran 说了什么。我的抽象类实际上没有方法。并非所有写的都是正确的。 特别是在软件工程中。我在书籍/论文中看到了很多垃圾。
    • 有趣。我一直认为这是关于继承基数的。感谢您的澄清。
    【解决方案3】:

    抽象类 a 是基本的 OOP 概念,所以我认为您的问题不是特定于 UML。
    这里有一个关于何时使用抽象类的问题:

    Exact use of Abstract class

    基本上,当多个类共享一组功能但该功能没有意义或本身不完整时,您应该使用抽象类。只有抽象类才能包含抽象方法,供后代实现。

    例如,您可能希望将基本的 FileLogger 和 EmailLogger 功能提取到 Logger 类中,但是由于它本身没有意义,因此您只需将其抽象化即可。

    【讨论】:

      【解决方案4】:

      当您有多个具有相同功能的类时,一个类应该是抽象的,但每个此类的某些方法与超类(抽象类)不同。

      例如一只动物。每个动物类都有方法 isAlive()。这种方法对所有动物都是平等的。 每个动物都有方法 move(target)。但每一种动物的移动方式都不同。你不能笼统地谈论动物的运动。有些动物会飞,有些会游泳,有些会跑。

      【讨论】:

      • 奇怪Animal 总是可以用来表达这个概念 =)
      【解决方案5】:

      当您尝试表达子类化时,例如当您想要明确时,Cat 是 Animal 的一种特殊情况。

      例如,Animal 可以对某些行为进行一些基本实现,例如 Eat,可以在子类上重写。

      【讨论】:

        【解决方案6】:

        抽象类与普通类一样,只是它允许您在没有方法体的情况下定义方法头。

        这允许派生类有自己的实现,而基类没有自己的实现。

        【讨论】:

          【解决方案7】:

          一个抽象类意味着你可以维护一个方法或变量的列表(默认情况下在抽象类中是公共静态最终的)这会强制扩展这个抽象类的类来实现那些在声明的抽象类中没有实现的方法,(抽象类与接口有很高的相似度,但唯一的区别是接口是100%抽象类)。

          【讨论】:

            猜你喜欢
            • 2022-01-02
            • 1970-01-01
            • 2010-09-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-24
            • 2021-12-17
            • 1970-01-01
            相关资源
            最近更新 更多