如何使用超类型对枚举进行分组

我目前正在一个项目中工作,我有两个不同的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.
}

由于模式匹配、记录和密封类的进一步工作,未来可能会出现其他相关的漂亮特性。


警告:此设计(枚举共享已实现的接口)可能是也可能不是特定设计问题的合适解决方案。为了演示这种解决方案的方法,我在给定的示例中忽略了适当性问题。


以上是如何使用超类型对枚举进行分组的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>