use*_*745 7 java oop inheritance enums design-patterns
何时使用继承有一般的最佳实践:
public class Information {
private String text;
}
public class Message extends Information {
}
public class Faq extends Information {
}
public class News extends Information {
}
Run Code Online (Sandbox Code Playgroud)
以及何时使用枚举作为成员变量来区分:
public enum InformationType {
MESSAGE, FAQ, NEWS
}
public class Information {
private String text;
private InformationType type;
}
Run Code Online (Sandbox Code Playgroud)
在我使用的代码中,我有第二个 - 一个类型字段,困扰我的是代码
public void displayInformation(final Information information) {
if (information.getType == InformationType.MESSAGE) {
....
} else if (information.getType == InformationType.FAQ) {
....
} else if (information.getType == InformationType.NEWS) {
....
} else {
// some error handling
}
}
Run Code Online (Sandbox Code Playgroud)
这绝对是一种代码异味,我不明白您如何将枚举作为成员变量而没有这些 if-else!?如果这是真的,那么您永远不应该将枚举作为对象的类型,但我经常看到这种“模式”!
不同的工具适合不同的工作。
1. 使用枚举类声明一组编译时已知的固定常量。
枚举类可以方便和清晰地描述事物的好例子是:一副扑克牌中的西装和等级,以及太阳系中的行星。两个示例都有一个共同点,即对象是常量(或合理的常量;没有禁止演化枚举类的法律),并且都可以在程序执行开始时实例化。
枚举类在其他方面与普通 Java 类非常相似。您可以通过在枚举类中定义实例字段和构造函数来为每个常量添加特定于常量的数据,并且您可以通过编写特定于常量的方法来定义特定于常量的行为。
用 Java 编写丰富的枚举类型很容易,而且它们非常强大。使用得当,它们将使您的代码更加精简和易于维护。当您处理一组固定的常量对象时,枚举类通常是最佳选择。
具有特定于常量的方法的枚举通常使您的程序代码更易于阅读和健壮维护。例如,而不是:
public void displayInformation(final Information information) {
if (information.getType == InformationType.MESSAGE) {
....
} else if (information.getType == InformationType.FAQ) {
....
} else if (information.getType == InformationType.NEWS) {
....
} else {
// some error handling
}
Run Code Online (Sandbox Code Playgroud)
例如,您可以在 enum 类中定义一个抽象方法InformationType,displayInfo()然后像这样编写特定于常量的方法:
public enum InformationType {
MESSAGE {
@Override
public String displayInfo() {
....
}
},
FAQ {
@Override
public String displayInfo() {
....
}
},
:
:
LAST_TYPE {
@Override
public String displayInfo() {
....
}
};
abstract public String displayInfo();
}
Run Code Online (Sandbox Code Playgroud)
在丰富的枚举类型中以这种方式使用特定于常量的方法是在代码中使用 switch-case 块的一个很好的替代方案,它会很快变得非常难看。一旦你实现了这个丰富的枚举类型,你就可以用更清晰、更易于阅读的方法替换你的原始方法:
public void displayInformation(final Information information) {
information.getType().displayInfo();
}
Run Code Online (Sandbox Code Playgroud)
2. 当您希望使用与超类具有“是一个”关系的任意数量的对象时,请使用子类。
子类是扩展超类的普通 Java 类。使用这样的层次结构的正确时间是当您的类的实例都与超类具有“是”关系时。原型示例将是 superclassBicycle和 subclass MountainBike。所有山地自行车都是自行车。
如果子类和超类之间没有明确定义的“是一个”关系,那么最好不要使用继承(支持组合而不是继承)。
3. 避免使用枚举常量来描述层次结构的陷阱。
例如,您有一个Shape包含实例字段的类,该类包含类型为枚举的常量ShapeType(并且您将枚举类编写为具有常量 CIRCLE、RECTANGLE、TRIANGE)。
当此类标记类很简单时,有时使用实例字段作为标记是正确的做法,但要避免使用标记作为类层次结构的隐蔽伪装的陷阱。最好和最简洁的表示方式当然Shape是作为具有子类Circle、Rectangle、 和Triangle(所有这些形状)的抽象超类。