如何使用超类型对枚举进行分组
我目前正在一个项目中工作,我有两个不同的Enums应该填写在Array. 即我的 Array 应该能够容纳 Enum 之一。我知道您不能像使用类那样为 Enum 实现继承。
有没有办法对我的两个枚举进行分组,因此我可以将它们放入同一个数组中?
回答
enumJava 中的An隐式是Enum该类的子类。与大多数面向对象的语言一样,Java 不支持多重继承。所以你的枚举不能是任何其他类的子类。
共享一个接口
但是……枚举可以实现接口。因此,定义一个要由您的两个枚举实现的接口。
例如,让我们Breed为各种动物品种定义一个接口。
package work.basil.demo.multienum;
public interface Breed
{
}
定义两个枚举中的每一个,都实现该接口。
一些狗。
package work.basil.demo.multienum;
public enum DogBreed implements Breed
{
AUSTRALIAN_SHEPHERD , LABRADOR_RETRIEVER , BORDER_COLLIE
}
还有猫。
package work.basil.demo.multienum;
public enum CatBreed implements Breed
{
MAINE_COON , MANX , RUSSIAN_BLUE
}
在示例应用程序中试用它们。
package work.basil.demo.multienum;
import java.util.List;
public class App
{
public static void main ( String[] args )
{
List <Breed> breeds =
List.of(
DogBreed.BORDER_COLLIE,
CatBreed.RUSSIAN_BLUE,
CatBreed.MAINE_COON
);
System.out.println( "breeds = " + breeds );
}
}
跑的时候。
breeds = [BORDER_COLLIE, RUSSIAN_BLUE, MAINE_COON]
哎呀,我现在看到你要求一个数组。工作方式相同。
package work.basil.demo.multienum;
import java.util.Arrays;
import java.util.List;
public class App
{
public static void main ( String[] args )
{
Breed[] breeds =
List.of(
DogBreed.BORDER_COLLIE ,
CatBreed.RUSSIAN_BLUE ,
CatBreed.MAINE_COON
)
.toArray( new Breed[ 0 ] );
System.out.println( "breeds = " + Arrays.toString( breeds ) );
}
}
在这个例子中,我们没有在接口上定义任何方法Breed。请注意,如果您确实在那里添加了任何方法,则两个枚举都必须实现这些方法。如果省略,编译器会通知您。
类型和铸造
你在评论中问:
因此,我的接口将作为“超类型”工作,而无需定义任何要覆盖的内容。我理解正确吗?
是的。请注意我上一个示例中的数组声明。命名的变量breeds是一个类型对象数组Breed(接口)——不是CatBreed枚举对象数组,也不是DogBreed枚举对象数组。
你在评论中问:
如果枚举自己实现一个方法会发生什么?例如
CatBreed实现purr()方法。即使类型是 ,我仍然可以访问此方法Breed吗?
不。数组的元素都是Breed对象。因此,当用作 时Breed,这样的对象不会“看到”任何特定于 的方法CatBreed。一个Breed对象只能看到Breed接口上定义的方法。
要访问 cat 的purr方法,您必须将对对象的引用转换为对Breed对象的引用CatBreed。您将首先使用instanceof.
Breed breed = breeds.get( 1 ) // Index of 1 means second item, per annoying zero-based counting. We get `CatBreed.RUSSIAN_BLUE` as seen in the example code above.
if( breed instanceOf CatBreed ) // Test if the object referenced by `breed` happens to be also of type `CatBreed` besides being of type `Breed`.
{
CatBreed catBreed = (CatBreed) breed ; // Cast to that other type.
… // Use the `CatBreed` object named `catBreed` to access methods specific to `CatBreed` enum class.
}
Java 16 有一个新特性,JEP 394: instanceof 的模式匹配,使转换自动进行。
Breed breed = breeds.get( 1 ) // We get `CatBreed.RUSSIAN_BLUE` from earlier example.
if( breed instanceOf CatBreed catBreed ) // Casting is automatic in Java 16 and later.
{
… // Use the `CatBreed` object named `catBreed` to access methods specific to `CatBreed` enum class.
}
由于模式匹配、记录和密封类的进一步工作,未来可能会出现其他相关的漂亮特性。
警告:此设计(枚举共享已实现的接口)可能是也可能不是特定设计问题的合适解决方案。为了演示这种解决方案的方法,我在给定的示例中忽略了适当性问题。