如何使用 Java 严格实施给定的 UML?

How do I strictly implement the given UML using Java?

我正在尝试使用 Java:

来实现下面的 UML

我已经成功执行了每条指令,除了一条:

剧院class:

我是 UML 的新手,根据我的理解,我不能在任何 class 中创建构造函数。这很令人困惑,因为我不知道在哪里可以定义 showArea 的大小。

下面是我现在的工作代码。

放置Class

public abstract class Place {
    private String placeName;
    private int capacity;
    private String placeDescription;
    private int workingHours;


    public abstract void showEvents();
}

建筑Class

public abstract class Building extends Place{
    
    public abstract void showArea();
}

剧院Class

public class Theater extends Building{
    @Override
    public void showArea() {
        System.out.println("Theater area : " );
    }

    @Override
    public void showEvents() {
        System.out.println("Events ready to be hosted !!");
    }
}

主要class

public class CodingtonDemo {
    public static void main(String[] args) {
        Theater theater = new Theater();
        theater.showArea();
        theater.showEvents();
    }
}

控制台预期结果:

剧场面积:6000

活动准备就绪!!

我目前的成绩:

剧场区:[暂无数值]

活动准备就绪!!

你的代码和UML不一样,你的UML有问题。在你的图中,Place 是一个具体的 class,它是你的代码的抽象 class。没有理由在 Place class 中有私有属性,因为它们不能被它的 children 访问,所以它们的可见性应该被 protected 代替(UML 中的符号是#)。 building class 除了声明一个方法之外什么都不做,所以它可以被一个接口替换(在 UML 中你可以使用一个圆圈或使用接口构造型)而没有任何 Place 的继承,这个解决方案会影响剧院它不是 Building 的 child,而是实现 Building 接口的 Place 的 child。

关于您的代码,Theater class 中的 showArea 方法不显示任何值,那么您为什么期望 6000 值?如果您希望 6000 值来自 Place 的容量,首先您需要一个设置容量的方法(可能是 setter),在 Main class 中使用此方法,然后将容量保护为可以被 Theater 访问并最终在 showArea 方法中使用它。

你的图表有问题

您的图表是模型的部分表示:

  • Place的属性placeNameplaceDescriptioncapacityworkingHours都是私有的(-).这意味着它们对于 BuildingTheater 均不可访问。既然你没有构造函数也没有setter,这些属性怎么会有用呢?并且由于您没有 public getter,这些值如何用于更专业的 classes 的任何 showXxxx() 操作?

  • 既然 Building 无法访问私有属性,也没有其他属性,那么 showArea() 怎么能提供任何有用的东西呢?

  • 最后,您对 Theatre 中的覆盖是正确的。但是您诊断出的缺失大小及其初始化的问题已经适用于 Building.

因此,如果您严格遵守您的图表并且不添加任何其他隐式操作,您将永远无法在控制台上获得预期的结果。我希望这不会让您感到震惊。这是支持我的声明的 UML 规范引用:

11.4.3.1: (...) A Class cannot access private Features of another Class, or protected Features on another Class that is not its ancestor.

语法上的小问题,您可以改进:

  • 斜体符号用于 class 名称以证明它们是抽象的。它不再为抽象操作正式定义,尽管许多人(我这样说是因为我自己这样做)仍然使用这种表示法。因此,对具有实现的操作使用斜体是完全不明确的。

  • void 不是标准的 UML 类型。 returning void 操作仅在没有 return 类型的情况下指示。

  • showEvents in Theater 配一对大括号 ().

完成图表

您可以添加缺少的 getter 和 setter。您可以按照 UML 规范中的说明定义构造函数:

11.4.4: (...) A constructor is an Operation having a single return result parameter of the type of the owning Class, and marked with the standard stereotype «Create». The InstanceSpecification that is the supplier of the usage dependency represents the default value of the single return result parameter of a constructor Operation.

这看起来像:

«Create» Place(...) : Place

您现在可以完成图表并获得预期的结果。

可能需要更多改进:

  • 如果 Place 没有实现任何操作,您应该将其抽象化,因为它无法实例化。
  • 您可以使用图中的 {redefines ...} 显式覆盖。但这不是必须的。
  • 考虑到 showEvents() 并且看不到其他事件,我猜想缺少与事件 class 或接口的关系...

重新考虑您的设计

剧院是建筑物吗?在我的镇上,有一栋建筑有一个购物中心和一个剧院。所以我的建议是 prefer composition over inheritance.