when I declare a class `MyClass` and an interface ...
# getting-started
m
when I declare a class
MyClass
and an interface
MyInterface
and have several classes extending and implementing them, Kotlin infers both the class and the interface in generic types. For example
val list = listOf(ImplemA(), implemB())
contains objects that are
MyClass
and comply with
MyInterface
. IDEA describes the bound as
<{MyClass & MyInterface}>
in that case. Can I specify a type like that explicitly, without creating a new class? What's the catch?
d
Like where?
If the same type parameter needs more than one upper bound, you need a separate where -clause:
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
where T : CharSequence,
T : Comparable<T> {
return list.filter { it > threshold }.map { it.toString() }
}
The passed type must satisfy all conditions of the where clause simultaneously. In the above example, the T type must implement both CharSequence and Comparable.
m
No, I know that. I'm talking about this case:
Copy code
open class MyClass(val value: Int)
interface MyInterface {
    fun someMethod()
}

class ImplA : MyClass(2), MyInterface {
    override fun someMethod() {
        println("I am A")
    }
}

class ImplB : MyClass(5), MyInterface {
    override fun someMethod() {
        println("I am B")
    }
}

fun main() {
    val impls = listOf(ImplA(), ImplB()) // this a List<{MyClass & MyInterface}>

    for (ele in impls) {
        ele.someMethod()
        println("Its value is ${ele.value}")
    }
}
this is valid code, and will print
Copy code
I am A
Its value is 2
I am B
Its value is 5
But it works because Kotlin knows every element in the list is
MyClass
and
MyInterface
. What if I want to have that explicitly in the code?
and without writing a weird wrapper, ofc. Is that even possible? Ok I'm gonna go ahead and say it's probably not possible and all Kotlin's doing is just being very smart at casting for me, since this is just a
List
in the JVM due to type erasure
d
You can not declare intersection type explicitly. It is not-denotable type (e.g. like
String!
from java) and such types can be produced only by type inference https://youtrack.jetbrains.com/issue/KT-13108