在kotlin中使用Interface时获取平台声明冲突
我将Java中的一些类转换为kotlin,并且在尝试从接口继承时遇到编译错误:
平台声明冲突:以下声明具有相同的JVM签名(getContentID()Ljava / lang / String;):
公开开放的乐趣get-content-id():String? public open fun getContentId():String?
这里是界面:
interface Media { val contentId: String val displayRunTime: String val genres: List<String> val programId: String val runTime: String val type: String }
这里是班级:
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 }
我是kotlin的超级新手。
你不需要声明override fun getContentId(): String?
,因为Media
接口的val contentId: String
已经被override val contentId: String?
覆盖了override val contentId: String?
。
您得到的错误意味着您声明的函数与已为contentId
属性(getter具有相同签名)生成的getter在JVM字节码中发生冲突。
在Kotlin中,您应该直接使用属性contentId
,而在Java中,您可以使用生成的访问器getContentId()
和setContentId(...)
。
另外,Kotlin不允许你用可为空的String?
覆盖非空的String
属性String?
一个,因为基本接口的用户会期望属性的非空值。 你应该用String
替换重写的属性类型,或者使它们成为String?
在界面中。
主要问题是T?
型T?
包括T
和null
。 反过来, T
是T
的一个子集T?
。 所以你不能用超集类型覆盖T
属性,例如:
interface Source { val content: Any } // v--- ERROR: `Any?` is not a subtype of `Any` class Image(override val content:Any?) : Source
但是,你可以重写T?
属性及其子类型或子类型 ,例如:
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
那么你的代码应该如下。 但是,Kotlin是一个空安全系统,即使属性是可以为空的属性,也不能定义一个属性而不初始化它:
class Airing : Media { // v--- ERROR: the property isn't initialized override val contentId: String ... }
您应该在主构造函数中引入属性,让客户端代码在将来进行初始化,例如:
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
您也可以为属性提供一些默认值,例如:
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>" }
getContentId
函数会和getter
冲突,所以你应该删除它。
声明为val
的变量就像Java final
变量一样,是不可变的,所以你不能设置为Optional ?
你的变量声明应该如下所示:
interface Media { var contentId: String? //... }
- 在房间中更改Flowable <List <Obj1 >>为Flowable <List <Obj2 >>
- Kotlin Anko自定义视图父范围
- 点击ViewHolder中的RecyclerView项目
- Kotlin android扩展,软件包不能被导入
- 错误:Jack需要支持Java 8语言功能。 启用插件或删除sourceCompatibility JavaVersion.VERSION_1_8
- 在android中获取特定.sql文件的表大小
- findViewById ClassCastExcpetion
- 使用Kotlin和Firebase通过onAuthStateChanged回调触发sendEmailVerification
- Android工作室突然未能解决其他模块的依赖关系