java - 我可以使用接口(interface)作为枚举中的变量吗?

标签 java enums interface

我正在尝试使用接口(interface)作为枚举中的变量:

界面示例


public interface TestInterface {

void printMessage();

}

实现接口(interface)的类


public class TestClass implements Test {

 @Override
    public void printMessage() {

        System.out.println("This is a test");

    }

}

然后我们就有了枚举

public enum TestEnum {

TEST1(TestClass);

private final TestInterface interface;

TestEnum(TestInterface interface) {
   this.interface = interface;
}

}

只是一个简单的例子。我正在尝试类似的方法,但它不允许我使用实现接口(interface)的类作为枚举中的值。我在谷歌上搜索过,但找不到任何关于此的信息。

我可以这样做吗?据我了解,我可以使用该类,因为它实现了接口(interface)?我还缺少什么吗?

最佳答案

Java 中的枚举是一个类,特别是 Enum 的子类,对象会自动实例化并分配给编译时确定的名称。

  • 枚举可以实现接口(interface)。这意味着枚举中实例化和命名的每个对象都提供该方法。
  • 可以使用枚举来保存对接口(interface)对象的引用,该引用是其每个命名实例上的成员变量。

让我们分别看看。

实现接口(interface)的枚举

是的,枚举可以实现接口(interface)。与任何其他类一样,使用 implements 关键字进行定义并实现必要的方法。

假设我们有一个带有单一方法speak的接口(interface)Animal

package work.basil.example;

public interface Animal
{
    String speak();
}

我们可以创建一个实现该接口(interface)的枚举。这意味着该枚举类的所有命名对象都提供该行为。

package work.basil.example;

public enum GrannyPet implements Animal
{
    // Enum objects, automatically instantiated when this class loads.
    TWEETY(),
    SYLVESTER(),
    HECTOR();

    @Override
    public String speak ()
    {
        return "talk";
    }
}

让我们通过在每个枚举实例上调用该方法来尝试该行为。

    Set < GrannyPet > grannyPets = EnumSet.allOf( GrannyPet.class );
    for ( GrannyPet grannyPet : grannyPets )
    {
        System.out.println( "Granny’s pet: " + grannyPet + " says: " + grannyPet.speak() );
    }

输出。

Granny’s pet: TWEETY says: talk

Granny’s pet: SYLVESTER says: talk

Granny’s pet: HECTOR says: talk

但我不认为这就是你的意思。

引用接口(interface)对象的枚举

我怀疑您想要一个枚举,其每个对象都引用特定类的对象。

是的,我们可以做到这一点。 Java 中的枚举可以有一个构造函数方法,并且该构造函数可以接受参数。因此,我们可以将所需接口(interface)的对象传递给实例化的每个枚举对象的构造函数。与任何枚举一样,这一切都会在加载枚举类时自动发生。

动物

让我们使用相同的界面,Animal

package work.basil.example;

public interface Animal
{
    String speak();
}

让我们定义三个实现该接口(interface)的类:BirdCatDog

package work.basil.example;

public class Bird implements Animal
{

    @Override
    public String speak ()
    {
        return "chirp";
    }
}

package work.basil.example;

public class Cat implements Animal
{
    @Override
    public String speak ()
    {
        return "meow";
    }
}

package work.basil.example;

public class Dog implements Animal
{
    @Override
    public String speak ()
    {
        return "bark";
    }
}

GrannyPet 枚举

修改我们的枚举,使其具有一个采用 Animal 参数的构造函数。将 Animal 对象存储在成员变量中。

所以现在 GrannyPet 枚举不实现接口(interface) Animal,它保存一个 Animal 类型的对象。

将此代码与上面的枚举代码进行比较,注意 TWEETY、SYLVESTER 和 HECTOR 如何在使用上面的空 () 括号时分别在此处接受参数。因此,TWEETY()TWEETY( new Bird() )

package work.basil.example;

public enum GrannyPet
{
    // Enum objects, automatically instantiated when this class loads.
    TWEETY( new Bird() ),
    SYLVESTER( new Cat() ),
    HECTOR( new Dog() );

    // Member variables.
    private Animal animal;

    // Constructor
    GrannyPet ( Animal animalArg )
    {
        this.animal = animalArg;
    }

    // Accessor, getter.
    public Animal getAnimal ()
    {
        return this.animal;
    }

}

最后,我们修改了调用枚举的代码:

grannyPet.speak()

…对此:

grannyPet.getAnimal().speak()

调用代码如下所示:

    Set < GrannyPet > grannyPets = EnumSet.allOf( GrannyPet.class );
    for ( GrannyPet grannyPet : grannyPets )
    {
        System.out.println( "Granny’s pet: " + grannyPet + " says: " + grannyPet.getAnimal().speak() );
    }

运行时。

Granny’s pet: TWEETY says: chirp

Granny’s pet: SYLVESTER says: meow

Granny’s pet: HECTOR says: bark

关于java - 我可以使用接口(interface)作为枚举中的变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56762239/

相关文章:

java - 如何重构重复的一行代码java

java - 如何确保我正在检查未选中的复选框 selenium java

java - 我如何告诉 Maven Artifact 已重命名?

c# - 为什么 Enum 上的 HasFlag 扩展方法胜过 Enum.HasFlag?

java - 创建一个可以处理所有类型的 CRUD 操作的类。每次我需要执行 CRUD 时,无需创建 SessionFactory 或 Session 对象

php - 在 php 变量中存储换行符

java - 如何克隆 JDT ICompilationUnit

enums - Kotlin - 将枚举值分配给没有 .value 的变量

c# - 没有任何成员的接口(interface) - 不好的做法?

c# - 关于C#中接口(interface)使用的问题