Reputation: 524
In my setup, I'm trying to have an interface Table
that inherits from Map
(because it will mostly be used as a wrapper around the map). Two classes inherit from Table
- local and global. The global one will have a mutable map, and the local one will have a map of only local entries.
// entries
sealed class Entry {
class EntryLocal : Entry
class EntryGlobal : Entry
}
interface Table : Map<String, Entry> {
fun getRecursive(key: String): Entry?
}
class GlobalTable(val map:MutableMap<String, Entry>) : Table, Map<String, Entry> by map {
override fun getRecursive(key: String) = this[key]
...
}
class LocalTable(
private val parent: Table,
val map: Map<String, EntryLocal>
) : Table, Map<String, EntryLocal> { // gives error
override fun getRecursive(key: String): Entry? = map[key] ?: parent.getRecursive(key)
}
I get the following error:
Type parameter V of 'Map' has inconsistent values: Entry, EntryVar
Why is that? Doesn't Map<String, EntryLocal>
inherit from Map<String, Entry>
?
Upvotes: 4
Views: 256
Reputation: 8204
You're right the value type of Map
is covariant and so a Map<String, EntryLocal>
is a Map<String, Entry>
.
However, that's not your problem here. The problem is that LocalTable
inherits from both Map<String, EntryLocal>
(directly) and Map<String, Entry>
(via Table
) so it's not clear what the value type should be in LocalTable
.
In other words, what's the return type of LocalTable.get
? Is it Entry
or EntryLocal
?
Here's the problem in a nutshell:
interface M<T> {}
interface A : M<String> {}
interface B : M<Object> {}
class C : A, B {}
You'll get the same error saying that parameter T
of M
has inconsistent values. Even though String
is an Object
, Kotlin won't assume that the type parameter T
of the base class M
should therefore be String
(or Object
).
Upvotes: 5