Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforcing the implementer of an interface to be an enum

I would like to store a type called App inside a set. App needs to be an enum that implements the App interface.

Set<App> myApps;

I have defined the interface like so...

interface App<T extends Enum<T>> {}

This is almost working, for example, you cannot do this...

class MyClass implements Application<MyClass> {}

However, you can do this...

enum MyEnum implements Application<MyEnum> {}
class Myclass implements Application<MyEnum> {}

Which is wrong. I only want enums to be able to implement this interface, how can I enforce this?

like image 721
Ogen Avatar asked Jul 22 '16 13:07

Ogen


People also ask

Can we implement interface in enum?

Yes, Enum implements an interface in Java, it can be useful when we need to implement some business logic that is tightly coupled with a discriminatory property of a given object or class.

Can we create enum in interface Java?

In short, yes, this is okay. The interface does not contain any method bodies; instead, it contains what you refer to as "empty bodies" and more commonly known as method signatures. It does not matter that the enum is inside the interface.

Can enum implement interface C#?

After a bit of experimentation, my conclusion is that it's possible for an enum to implement an interface if it doesn't have methods. But you cannot create it in C#. Using that enum in a C# program is funny: if you check if the value "is IMyInterface", the compiler warns you that the expression is never of that type.

Can a class extend enum in Java?

No, we cannot extend an enum in Java. Java enums can extend java. lang. Enum class implicitly, so enum types cannot extend another class.


2 Answers

Define a method that allows you to add Elements into the set, BUT use a constraint for that parameter...

 public <E extends Enum<E> & IMyInterface> void addToSet(final E value) { }

now after that

addToSet(MyEnum.K) will compile

but

addToSet(new Myclass()) will NOT compile
like image 198
ΦXocę 웃 Пepeúpa ツ Avatar answered Oct 08 '22 20:10

ΦXocę 웃 Пepeúpa ツ


AFAIK it is not possible to enforce an implementor of an interface to have certain properties such as being an enum.

However, depending on your code and how you use that interface you can make it hard for someone not to make the implementor an enum:

  • Require T to implement App<T> as well to prevent passing any enum to the class declaration (i.e. App<T extends Enum<T> & App<T>>)
  • Use additional boundaries when possible (see ΦXocę 웃 Пepeúpa's answer)
  • Add methods that are already implemented by Enum such as name(), ordinal(), getDeclaringClass() etc.
  • Let App<T ...> extend Comparable<T>.
  • When possible call getClass().isEnum() to check that property at runtime. This is not ideal but there are similar solution's that are commonly used such as Collections.unmodifiableSet().
like image 34
Thomas Avatar answered Oct 08 '22 19:10

Thomas