我需要创建一个需要表示以下内容的结构(对于类别和子类别)。它只有一层深度。我正在考虑使用Java Enums进行操作,并且不确定如何表示这种层次结构。
我代表设备的java对象(业务对象)将同时具有类别和子类别属性,我想使用Enum而不是使用整数代码,如100,1等。有些设备只有类别但不是子类别(如下例中的300)。
100 Switch
1 Interior
2 Exterior
200 Security Sensor
1 Door Sensor
2 Leak Sensor
3 Motion Sensor
300 Camera
感谢任何帮助。
由于
答案 0 :(得分:3)
此java.dzone文章展示是分层枚举的一个很好的例子:
public enum OsType {
OS(null),
Windows(OS),
WindowsNT(Windows),
WindowsNTWorkstation(WindowsNT),
WindowsNTServer(WindowsNT),
Windows2000(Windows),
Windows2000Server(Windows2000),
Windows2000Workstation(Windows2000),
WindowsXp(Windows),
WindowsVista(Windows),
Windows7(Windows),
Windows95(Windows),
Windows98(Windows),
Unix(OS) {
@Override
public boolean supportsXWindows() {
return true;
}
},
Linux(Unix),
AIX(Unix),
HpUx(Unix),
SunOs(Unix),
;
private OsType parent = null;
private OsType(OsType parent) {
this.parent = parent;
}
}
这篇文章展示了一些可以通过此设置实现的小技巧。
答案 1 :(得分:2)
我认为this answer对您来说是一个很好的解决方案。使用类似这样的类型层次结构:
public enum Component {
Interior(Part.Switch),
Exterior(Part.Switch),
DoorSensor(Part.SecuritySensor),
LeakSensor(Part.SecuritySensor),
MotionSensor(Part.SecuritySensor),
Camera(Part.Camera);
private final Part kindOf;
Component(Part kindOf) {
this.kindOf = kindOf;
}
enum Part {
Switch, SecuritySensor, Camera
}
}
更多细节可以在 Effective Java 2nd Edition 的章节枚举中找到。
答案 2 :(得分:1)
你想用枚举而不是继承来表达这一点似乎很不寻常。枚举的内容是它们本质上是编译时常量,如果您想在层次结构中生成更多信息,则必须添加更多枚举。
那可能会变得凌乱,快速。它也与枚举的真正目的略有矛盾 - 作为预定义常量而不是分层实体。
我建议使用一个名为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
,所以我们不会传递任何内容到构造函数的vararg部分。
对于 具有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"));
}
}
这种方法为您提供了一些围绕排名的灵活性 - 如果您希望能够在运行时指定子类别的确切排名,您可以将此构造函数替换为支持的构造函数vararg签名。
答案 3 :(得分:0)
您可以执行以下代码之类的操作。但这可能不是你想要的。您可以将子枚举添加到父{1}}之类的父枚举的构造函数中。
enum Stuff {
Swich,Sensor,Camera;
enum swich {
interior,exterior;
enum Where {
bathroom,kitchen
}
}
enum sensor {
door,leak,motion
}
}
答案 4 :(得分:0)
也许重新考虑并在这里使用整数。但是,不是将它们基于十进制系统(100,200,300,......用于第一级; 1,2,3,......用于第二级),而是基于二进制表示。
// top-level
public static final int SWITCH = 1 << 16;
public static final int SECURITY_SENSOR = 2 << 16;
public static final int CAMERA = 4 << 16;
// sub-types of 'switch'
public static final int INTERIOR = SWITCH | 1;
public static final int EXTERIOR = SWITCH | 2;
// sub-types of 'security sensor'
public static final int DOOR_SENSOR = SECURITY_SENSOR | 1;
public static final int LEAK_SENSOR = SECURITY_SENSOR | 2;
public static final int MOTION_SENSOR = SECURITY_SENSOR | 4;
这允许您进行弱形式的继承测试:
if (value == SWITCH) {
// value is a switch, but not interior or exterior
} else if (value & SWITCH != 0) {
// value is interior or exterior
}
答案 5 :(得分:-1)
以下代码是否符合您的要求?
public enum Category {Switch, ...}
public enum SubCategory {Interior, ...}