【问题标题】:How do I strictly implement the given UML using Java?如何使用 Java 严格实现给定的 UML?
【发布时间】:2021-01-01 02:05:58
【问题描述】:

我正在尝试使用 Java 实现下面的 UML:

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

戏剧课:

  • 覆盖 showArea 方法并显示大小乘以 12。

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

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

地方课

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


    public abstract void showEvents();
}

建筑类

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

戏剧课

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 !!");
    }
}

主类

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

控制台中的预期结果:

剧院面积:6000

活动准备就绪!!

我目前的结果:

剧院区:[尚无价值]

活动准备就绪!!

【问题讨论】:

  • 为什么在你的UML图中所有的成员都是用斜体写的?图中没有说明 PlaceBuilding 是抽象的。 showEVents: void 在操作室中是非法的。在全球范围内,您的图表无效
  • @bruno UML 中没有说明 PlaceBuilding 是抽象的,但 showEvents() 方法必须是抽象的。如果我错了,请纠正我,但是我无法在具体类中实现抽象方法。另外,你能告诉我更多关于 showEvents:void 是如何非法的吗?
  • showEvents() method must be abstract:为什么?在图中没有任何说明,它是斜体的事实没有任何价值,因为正如我所说的那样,all 包括属性的成员都是斜体的,这是非法的。 I can't implement abstract methods in concrete classes :根据定义,没有实现抽象操作,否则它不是抽象的。你可以随意混合,抽象类可以有抽象和非抽象操作。 ...
  • ...您在回答The UML was given to me as an exercise thus I have no control to how it was made 的备注中说,联系为您提供图表练习的人以传输错误并要求提供有效图表,事实上该人是老师什么都不改变。
  • @bruno 感谢您花时间解释这一切。我将尝试向进行图表练习的人询问有关 UML 错误的信息。

标签: java inheritance uml abstract-class


【解决方案1】:

图表的问题

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

  • Place 的属性 placeNameplaceDescriptioncapacityworkingHours 都是私有的 (-)。这意味着BuildingTheater 都无法访问它们。既然你没有构造函数也没有setter,这些属性怎么会有用呢?并且由于您没有公共 getter,这些值如何在更专业的类的任何 showXxxx() 操作中使用?

  • 由于Building 无法访问私有属性并且没有其他属性,showArea() 如何提供有用的东西?

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

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

11.4.3.1:(...) 一个类不能访问另一个类的私有特性,或另一个非其祖先类的受保护特性。

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

  • 斜体表示类名是为了说明它们是抽象的。它不再被正式定义为抽象操作,尽管许多人(我这么说是因为我自己做的)仍然使用这种表示法。因此,对有实现的操作使用斜体是完全模棱两可的。

  • void 不是标准的 UML 类型。返回 void 的操作只是表示没有返回类型。

  • Theater 中的showEvents 需要一对大括号()

完成你的图表

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

11.4.4: (...) 构造函数是具有单个返回结果参数的操作,该参数属于所属类的类型,并使用标准构造型«Create» 进行标记。 InstanceSpecification 是使用依赖的提供者,表示构造函数 Operation 的单个返回结果参数的默认值。

这看起来像:

«Create» Place(...) : Place

您现在可以完成图表并实现预期结果。

可能需要更多改进:

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

重新考虑您的设计

剧院是建筑物吗?在我的镇上,有一栋大楼设有商场和剧院。所以我的建议是prefer composition over inheritance

【讨论】:

  • 感谢您。我已经接受严格遵循 UML 不可能达到我的预期结果。
【解决方案2】:

您的代码和 UML 不相等,您的 UML 有一些问题。在您的图中, Place 是一个具体的类,它是您的代码的一个抽象类。没有理由在 Place 类中具有私有属性,因为它们的子级无法访问它们,因此它们的可见性应该由 protected 代替(UML 中的符号是#)。构建类除了声明一个方法之外什么都不做,所以它可以被一个接口替换(在 UML 中你可以使用一个圆圈或使用接口原型)而不继承任何 Place,这个解决方案会影响 Theatre 而不是Building 的子代,将成为实现 Building 接口的 Place 的子代。

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

【讨论】:

  • 免责声明:UML 是作为练习提供给我的,因此我无法控制它是如何制作的。关于 Place 类是抽象的,如果仔细看的话 ShowEvents() 需要是一个抽象方法,因此我选择将 Place 也设为抽象类。关于预期值,正如我所说,问题和 UML 给了我,如果你再次阅读我的问题,我已经说明了我尚未实现的指令,这可能导致在运行代码后获得 6000 的值.
  • 你混合了抽象类和抽象操作。你的所有类都没有被定义为抽象的。
猜你喜欢
  • 2022-01-03
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多