【问题标题】:Am I allowed to use an interface as a variable in an enum?我可以在枚举中使用接口作为变量吗?
【发布时间】:2019-06-25 21:28:18
【问题描述】:

我正在尝试将接口用作枚举中的变量:

示例界面


public interface TestInterface {

void printMessage();

}

实现接口的类


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;
}

}

只是一个简单的例子。我正在尝试类似的东西,它不允许我使用实现接口的类作为枚举中的值。我在谷歌上搜索过,找不到任何东西。

我什至可以这样做吗?我的理解是我可以使用该类,因为它实现了接口?我还有什么遗漏的吗?

【问题讨论】:

  • 您可以使用该类的object,但不能使用该类本身。 TEST1(new TestClass()) 应该可以工作。
  • 试试TEST1(new TestClass());
  • 您使用关键字interface 作为变量名;您需要更改该名称。另外,我假设您的意思是TestClass implements TestInterface
  • new TestClass() 工作了,谢谢

标签: java enums interface


【解决方案1】:

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

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

让我们来看看这些。

实现接口的枚举

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

假设我们有一个接口 Animal 和一个方法 speak

package work.basil.example;

public interface Animal
{
    String speak();
}

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

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() );
    }

输出。

奶奶的宠物:TWEETY 说:说话

奶奶的宠物:SYLVESTER 说:说话

奶奶的宠物:HECTOR 说:说话

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

引用接口对象的枚举

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

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

Animal

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

package work.basil.example;

public interface Animal
{
    String speak();
}

让我们定义三个实现该接口的类,BirdCatDog

Bird

package work.basil.example;

public class Bird implements Animal
{

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

Cat

package work.basil.example;

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

Dog

package work.basil.example;

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

GrannyPet枚举

修改我们的枚举,让构造函数接受Animal 的参数。将 Animal 对象存储在成员变量中。

所以现在GrannyPet 枚举没有实现接口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() );
    }

运行时。

奶奶的宠物:TWEETY 说:唧唧喳喳

奶奶的宠物:SYLVESTER 说:喵

奶奶的宠物:HECTOR 说:吠声

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多