Kotlin. Interface as parameter

Viewed 119

I am storing static data in an Enum. There can be many of them, but they have the same structure, which is specified by a special interface, to simplify work with all of them. I used similar logic in Swift and it works, but Kotlin does not allow me to use such logic.

interface DataElement {
    val code: UInt
    val name: String
}

enum class DataEnum1: DataElement {

    Apple {
        override val code: UInt
            get() = 1u
    },

    Orange {
        override val code: UInt
            get() = 2u
    },

    Watermelon {
        override val code: UInt
            get() = 3u
    }
}

enum class DataEnum2: DataElement {

    Blueberry {
        override val code: UInt
            get() = 4u
    },

    Strawberry {
        override val code: UInt
            get() = 5u
    },

    Blackberry {
        override val code: UInt
            get() = 6u
    }
}

Here's the problem

fun someFun() {
  val array = DataEnum1.values()
  anotherFun(array) // TYPE MISMATCH
  //Required:
  //Array<PeripheralDataElement>
  //Found:
  //Array<DataEnum1>
}
    
fun anotherFun(items: Array<DataElement>) {
     // some logic
}
1 Answers

Arrays are invariant in Kotlin, meaning that you cannot directly pass a Array<SubClass> to a function accepting Array<SuperClass>. However, you could define your function like this to make it accept a covariant array:

fun anotherFun(items: Array<out DataElement>) {
    // ...
}

Now your function also accepts Array<SubClass>.

Side note: This automatically works with lists because List is defined as covariant in it's type argument on the interface level, like interface List<out T>.

Related