Accepting platform creation announcement when using frontend in kotlin
I am converting some classes in Java to kotlin and I am running compilation errors when I try to inherit from an interface:
Platform declaration collision: The following declarations have the same JVM signature (getContentID () Ljava / lang / String;):
public open fun get-content-id (): String? public open fun getContentId (): String?
Here is the interface:
interface Media {
val contentId: String
val displayRunTime: String
val genres: List<String>
val programId: String
val runTime: String
val type: String
}
here is the class:
class Airing : Media {
override val contentId: String? = null
override val displayRunTime: String? = null
override val genres: List<String>? = null
override val programId: String? = null
override val runTime: String? = null
override val type: String? = null
override fun getContentId(): String? {
return contentId
}
I am super new to kotlin.
source to share
You don't need to declare override fun getContentId(): String?
because val contentId: String
from interface is Media
already overridden override val contentId: String?
.
The error you are getting means that the function declaring conflicts in the JVM bytecode with a getter that has already been generated for the property contentId
(the getter has the same signature).
In Kotlin, you have to work with the property contentId
directly, whereas in Java, you can use the generated accessors getContentId()
and setContentId(...)
.
Also, Kotlin does not allow overriding the not-null property String
with a null value String?
, since users of the base interface expect a non-null property value. You have to replace the overridden property types with String
or make them String?
in the interface.
source to share
The main problem is that the type T?
includes T
and null
. in turn T
is a subset of T?
. so you cannot override the property T
with your superset type, for example:
interface Source { val content: Any }
// v--- ERROR: `Any?` is not a subtype of `Any`
class Image(override val content:Any?) : Source
However, you can override a property T?
with a subset or subtype property , for example:
interface Source { val content: Any? }
// v--- `Any` is a subset of `Any?`
class Image(override val content:Any) : Source
// `String` is a subtype of `Any` & `Any?` includes `Any`
// v
class Text(override val content:String) : Source
Then your code should be as follows. However, Kotlin is a null safety system, you cannot define a property without initializing it, even if it is a nullable property :
class Airing : Media {
// v--- ERROR: the property isn't initialized
override val contentId: String
...
}
You have to inject properties into the primary constructor so that the client code will initialize them in the future, for example:
class Airing
constructor(
override val contentId: String,
override val displayRunTime: String,
override val genres: List<String>,
override val programId: String,
override val runTime: String,
override val type: String
) : Media
You can also provide a default value for properties, for example:
class Airing : Media {
override val contentId: String = "<default>"
override val displayRunTime: String = "<default>"
override val genres: List<String> = emptyList()
override val programId: String = "<default>"
override val runTime: String = "<default>"
override val type: String = "<default>"
}
And the getContentId
function conflicts with getter
, so you must remove it.
source to share