我是否可以将接口用作枚举中的变量?

时间:2019-06-25 21:28:18

标签: java enums interface

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

示例界面


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

}

一个简单的例子。我正在尝试类似的操作,但不允许我使用实现接口的类作为枚举中的值。我已经在Google上搜索,但找不到任何内容。

我什至允许这样做吗?据我了解,由于可以实现该类,因此可以使用该类?还有其他我想念的东西吗?

1 个答案:

答案 0 :(得分:0)

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说:说话

     

奶奶的宠物:西尔维斯特说:说话

     

奶奶的宠物:赫克托说:说话

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

枚举引用接口的对象

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

是的,我们可以这样做。 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说:rp

     

奶奶的宠物:西尔维斯特说:喵

     

奶奶的宠物:HECTOR说:树皮