问题描述
我正在尝试使用 Java 实现下面的 UML:
我已经成功地实现了每一条指令,除了一条:
戏剧课:
我是 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
活动准备好举办!!
我目前的结果:
剧院区:[暂无价值]
活动准备举办!!
解决方法
你的图表有问题
您的图表是您模型的部分表示:
-
Place
的属性placeName
、placeDescription
、capacity
、workingHours
都是私有的 (-
)。这意味着它们对于Building
和Theater
都不可访问。既然你没有构造函数也没有 setter,那么这些属性怎么会有用呢?并且由于您没有公共 getter,如何在更专业的类的任何showXxxx()
操作中使用这些值? -
既然
Building
无法访问私有属性,也没有其他属性,那么showArea()
如何提供有用的东西? -
最后,您对
Theatre
中的覆盖是正确的。但是您针对缺失大小及其初始化诊断的问题对于Building
已经成立。
因此,如果您严格遵守图表并且不添加其他隐式操作,您将永远无法在控制台上获得预期的结果。我希望这不会让你感到震惊。这里是支持我的声明的 UML 规范引用:
11.4.3.1:(...) 一个类不能访问另一个类的私有特性,或另一个不是其祖先的类上的受保护特性。
小语法问题,您可以改进:
-
斜体符号用于类名以证明它们是抽象的。它不再是为抽象操作正式定义的,尽管很多(我这么说是因为我自己这样做)仍然使用这种表示法。因此,对具有实现的操作使用斜体是完全不明确的。
-
void
不是标准的 UML 类型。返回 void 的操作只是表示没有返回类型。 -
showEvents
中的Theater
需要一对大括号()
。
完成图表
您可以添加缺少的 getter 和 setter。您可以按照 UML 规范中的说明定义构造函数:
11.4.4: (...) 构造函数是一个具有所属类类型的单个返回结果参数的操作,并标有标准构造型 «Create»
。作为用法依赖项的提供者的 InstanceSpecification 表示构造函数 Operation 的单个返回结果参数的默认值。
这看起来像:
«Create» Place(...) : Place
您现在可以完成图表并实现预期结果。
可能需要更多改进:
- 如果
Place
没有实现任何操作,您应该将其设为抽象,因为它无法被实例化。 - 您可以使用图中的
{redefines ...}
明确覆盖。但这不是必需的。 - 考虑到
showEvents()
并且看不到其他事件,我猜是缺少与 Event 类或接口的关系...
重新考虑您的设计
剧院是建筑物吗?在我所在的镇上,有一栋拥有购物中心和剧院的建筑。所以我的建议是prefer composition over inheritance。
,您的代码和 UML 不相等,您的 UML 存在一些问题。在你的图中,Place 是一个具体的类,它是你的代码的抽象类。没有理由在 Place 类中有私有属性,因为它们的子类不能访问它们,所以它们的可见性应该替换为 protected(UML 中的符号是 #)。建筑类除了声明一个方法之外什么都不做,所以它可以被一个接口代替(在 UML 中你可以使用一个圆或使用接口构造型)而没有任何 Place 继承,这个解决方案会影响剧院,而不是被Building 的子代,将成为实现 Building 接口的 Place 的子代。
关于您的代码,Theater 类中的 showArea 方法不显示任何值,那么您为什么会期望 6000 值?如果您希望 6000 值来自 Place 的容量,首先您需要一个设置容量的方法(可能是一个 setter),在 Main 类中使用此方法,然后将容量保护为可供 Theatre 访问,最后使用它在 showArea 方法中。