秘密类或我如何停止计数并爱上枚举器






4.92/5 (35投票s)
了解如何在 Java 中使用枚举。
引言
本文将探讨 `enum` 类型的一些用途。 我不知道你怎么样,但我喜欢使用枚举。人们普遍认为 `enum` 类型提供了一组可能的值,并且是 `switch` 语句所必需的。就这些了吗?大错特错。
`enum` 类型是一个类。记住这一点,`enum` 的可扩展性就非常强大。它不仅仅可以用来表示属性的固定值,还可以用于更多用途。
一切皆对象
我从一个简单的前提开始。`enum` 类型定义了一个具有固定数量实例的类。 就像任何类一样,它可以有成员变量和方法,在一个简单的结构中提供整个 Java 世界。
public enum Season
{
SUMMER,
WINTER,
AUTUMN,
SPRING
}
这里有一个类,名为 `Season`,它有四个固定的实例。重要的是要记住这一点,因为你拥有的四个对象正是赋予 `enum` 简单结构和强大力量的原因。这种力量誓要用于善途。
`enum` 的常见用途是在 `switch` 语句中,例如:
String getForcast(Season season)
{
switch (season)
{
case SUMMER:
{
return "Sun, sun, sun";
}
case AUTUMN:
{
return "Cold and blustery";
}
case WINTER:
{
return "Snow and ice";
}
case SPRING:
{
return "Overcast with showers";
}
}
return null;
}
“等等!枚举器的元素都是对象,所以它们不能只是有一个方法来返回预测吗?” 你可能会问。说得好。这正是正确的做法。一个成员变量、一个方法和一个简单的构造函数,你就可以开始了。
public enum Season {
SUMMER("Summer", "Sun, sun, sun"),
WINTER("Winter", "Snow and ice"),
AUTUMN("Autumn", "Cold and blustery"),
SPRING("Spring", "Overcast with showers");
private final String seasonName;
private final String forcast;
private Season(String seasonName, String forcast)
{
this.seasonName = seasonName;
this.forcast = forcast;
System.out.println("Creating " + this);
}
String getForcast()
{
return this.forcast;
}
public String toString()
{
return seasonName + "{" + forcast + '}';
}
}
我包含了一个友好的字符串描述,并重写了 `toString()` 方法。
现在,不必在 `Season` 之外编写一个将值作为参数的方法,可以直接调用这些值来获取该值。
String forcast = Season.WINTER.getForcast();
存在的不可变性 [一个枚举]
如果你观察力敏锐,会发现成员变量都被标记为 `final`。这并非强制要求,但绝对值得鼓励。
因此,每个枚举都是一个对象,它可以拥有变量、方法,以及所有低空杂技表演。这些不仅仅是对象,它们的特殊状态意味着它们必须被视为不可变对象。它们并非完全不可变,但采取这种视角是好的。
由于是 `enum`,因此不需要 `hashCode()` 和 `equals()` 方法。每个实例都是唯一的,并且其相等性是固定的。因此,建议不要更改它们的状态。
需要功能吗?
我上面展示了枚举对象可以拥有属性和方法的方式。有时,某个操作的行为必须根据枚举的值而有所不同。这可以通过一个由每个枚举覆盖的抽象方法来实现,也可以通过一个功能类来提供行为。
首先是抽象方法
public enum Season
{
SUMMER("Summer", "Sun, sun, sun")
{
boolean willItRain()
{
return false;
}
},
//...
SPRING("Spring", "Overcast with showers")
{
boolean willItRain()
{
return true;
}
};
//...
abstract boolean willItRain();
}
这可行,但可扩展性不高,如果只有几个覆盖,枚举类很快就会变得混乱。是时候将工作委托给一个功能类了;进入枚举工厂方法。
我们首先将所有预测移出 `enum` 类。我们有一个基类 `SeasonFunctions`,它是抽象的,然后是四个可爱的子类,它们可以以任何适合它们的方式实现功能。
abstract class SeasonFunctions {
private final String seasonName;
private final String forcast;
SeasonFunctions(String seasonName,
String forcast)
{
this.seasonName = seasonName;
this.forcast = forcast;
System.out.println("Creating " + this);
}
abstract boolean willItRain();
abstract int dayTimeHigh();
abstract int nightTimeLow();
String getForcast()
{
return this.forcast;
}
public String toString()
{
return "SeasonFunctions{" + this.getSeasonName() + "}";
}
String getSeasonString()
{
return this.getSeasonName() + "{" + this.getForcast() + '}';
}
private String getSeasonName()
{
return this.seasonName;
}
}
历史
初步提交 - 更多内容即将到来。