Hey, is it possible to make an abstract enum ? Or ...
# getting-started
a
Hey, is it possible to make an abstract enum ? Or a type that is equal to Enum<T> with added methods ?
j
Enums can have any method you want, they are regular classes apart from the fact that they have a fixed known set of instances. However they can't be abstract allow subclasses by definition, because it would indirectly allow more instances
You can for instance write:
Copy code
enums class MyEnum {
    VALUE1, VALUE2;

    fun myFun(): Int = 42
}
r
They're kind of always abstract...
Copy code
enum class Foo {
  Foo1 {
    override fun something() = 1;
  },
  Foo2 {
    override fun something() = 2;
  };
  abstract fun something(): Int;
}
j
Right, maybe my initial comment is misleading in this respect. I meant they can't be abstract or open in the sense that you can't create subclasses of them
r
Oh, agreed, sorry wasn't trying to be snide - just wanted the OP to know it was possible to have abstract members.
j
No worries, I didn't take it that way 🙂 It's actually really worth pointing that out, because maybe the OP is interested in providing different implementations for different enum values. So thanks!
a
Thanks but it's not exactly what I meant, I need an interface or an abstract class to extend
Enum<*>
, then I need multiple Enum classes to implement this interface And I need this type for multiple methods where I have a selector of selectors (drop-downs) for an UI app
j
I'm not sure I understand your use case well. In particular, why can't you use a regular interface and make your enum classes implement that interface? (In other words, why is it important that the interface itself needs to be a subtype of
Enum
- which btw is not possible)
By the way, I believe you should be able to define a method that only accept enums that implement a particular interface:
Copy code
fun <T> myFun(value: T): Unit where T: Enum<T>, T: MyInterface {
    // value is both an Enum and a MyInterface
}
Can't double check the code, I'm on mobile right now. See the doc there: https://kotlinlang.org/docs/generics.html#upper-bounds
👌 1
r
It does work. There's not a lot on
Enum
that's useful (just
name
and
ordinal
), but if you make the type reified you can get the set of values, which might be useful:
Copy code
inline fun <reified T> myFun(value: T) where T: Enum<T>, T: MyInterface {
  println(enumValues<T>().toSet())
}
Which in combo allows you to have generic interfaces - cool! Thanks Joffrey, opened up a new technique to think about in future:
Copy code
interface Wrapper<T> {
  val foo: T
}

enum class IntWrapper : Wrapper<Int> {
  E1 { override val foo = 1 },
  E2 { override val foo = 1 },
}

inline fun <reified A, B> myFun(value: A) where  A: Enum<A>, A: Wrapper<B> {

  // value is a Wrapper<B>
  val b: B = value.foo

  // and it's an Enum
  println(value.name)
  println(value.ordinal)

  // and you can get the values of that enum
  println(enumValues<A>())
}
a
And what if my function needs to return the values of the Enum ?
r
Return them?
Copy code
inline fun <reified A, B> myFun(value: A): List<A> where  A: Enum<A>, A: Wrapper<B> {
  return enumValues<A>().toList()
}
a
Yeah okay it was simple I was just tired, thanks for the help everyone !
m
If you need to define a hierarchy of finite set of types, maybe you should use sealed interfaces or classes. Although having enums implement the same interface could suffice for your case, as shown above.