似乎用枚举来表达这个问题不太寻常,相比继承。枚举的问题在于它们本质上是编译时常量,如果你想在层次结构中生成更多信息,则必须添加更多枚举。
这可能会很快变得混乱。 这也略微违反了枚举的真正目的 - 作为预定义常量而不是分层实体。
我建议使用一个名为
CategoryBase
的抽象类来绘制所有内容。 然后,根据此创建您的继承树。
下面是一个图示:
大部分的工作是持有属性,我们永远不希望这些属性在创建后被更改,因此我们可以让抽象类来持有它们。我们还将它们设为“final”,这样它们就无法被修改。
public abstract class CategoryBase {
protected final int ranking;
protected final String name;
protected final SubCategory[] subCategories;
protected CategoryBase(int ranking, String name, SubCategory... subCategories) {
this.ranking = ranking;
this.name = name;
this.subCategories = subCategories;
}
public int getRanking() {
return ranking;
}
public String getName() {
return name;
}
public SubCategory[] getSubCategories() {
return subCategories;
}
}
从这里开始,我们可以基于此构建我们的标记类 - 包括
SubCategory
,因为它实际上只是以不同的方式表示信息的持有者。
这也使得编写标记类变得简单明了。例如,这是
Camera
:
public class Camera extends CategoryBase {
protected Camera(int ranking, String name) {
super(ranking, name);
}
}
它与“SubCategory”非常相似-“SubCategory”没有任何嵌套的“SubCategory”,因此我们不会向构造函数的可变参数部分传递任何内容。
对于具有“SubCategory”的内容,我们需要在构建时实例化它们。这里以“SecuritySensor”为例。
public class SecuritySensor extends CategoryBase {
public SecuritySensor(int ranking, String name) {
super(ranking, name,
new SubCategory(1, "Door Sensor"),
new SubCategory(2, "Leak Sensor"),
new SubCategory(3, "Motion Sensor"));
}
}
这种方法还可以在排名方面提供一定的灵活性——如果您想要能够在运行时指定子类别的确切排名,您可以用支持可变参数签名的构造函数替换此构造函数。