您想用枚举而不是继承来表达这一点似乎很不寻常。枚举的问题在于它们本质上是编译时常量,如果您想在层次结构中生成更多信息,则必须添加更多枚举。
这可能会变得混乱,很快。它也与枚举的真正目的略有矛盾——作为预定义的常量而不是分层实体。
我建议使用一个名为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 没有任何嵌套的SubCategorys,因此我们不会向构造函数的可变参数部分传递任何内容。
对于确实有SubCategorys的东西,我们需要在构造时实例化它们。这里以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"));
}
}
这种方法也为您在排名方面提供了一些灵活性 - 如果您希望能够在运行时指定子类别的确切排名,您可以将此构造函数替换为支持可变参数的构造函数签名。