在当前的Java类中,我们有2个Java bean Clazz1和Clazz2,它们都扩展了超类SuperClazz。我们还有一个列表,我们迭代超类条目,可以是Clazz1或Clazz2:
List<SuperClazz> entries;
我们现在需要将代码转换为Kotlin,但由于数据类不支持继承,我们不确定解决问题的最佳方法,我们只是创建一个带变量的标准Kotlin类,扩展超类,并手动制作getter-setters?或者,有没有更好的方法呢?
答案 0 :(得分:1)
通常有2种(不是相互的)方法可以消除对类继承的需求:
将Clazz1
和Clazz2
之间共有的部分提取到单独的类中。即
data class SharedStuff(val a:Int, val b:String)
data class Class1(val stuff:SharedStuff, val other:String)
data class Class2(val stuff:SharedStuff, val specific:Int)
然后您可以在列表中使用
class Container {
private var items = listOf<()->SharedStuff>()
fun add(a:Class1) { items += { a.stuff } }
fun add(b:Class2) { items += { b.stuff } }
}
从上面的示例中可以很容易地理解,您可以提取一个界面来代表Class1
和Class2
中的常见内容,如下所示:
interface HasStuff { val stuff:SharedStuff }
data class SharedStuff(val a:Int, val b:String)
data class Class1(override val stuff:SharedStuff, val other:String) : HasStuff
data class Class2(override val stuff:SharedStuff, val specific:Int) : HasStuff
class Container {
private var items = listOf<HasStuff>()
fun add(a:HasStuff) { items += a }
}
请注意,我们不一定需要SharedStuff
作为课程。您还可以在共享界面上拥有更多成员,并且仍然可以实现简洁through Kotlin's delegation。 (但通常情况更好to have "small" interfaces)
答案 1 :(得分:1)
我们决定这样做:
interface HasStuff { val sharedDt:Int }
data class Class1(override val sharedDt:Int, val other:String) : HasStuff
data class Class2(override val sharedDt:Int, val specific:Int) : HasStuff
class Container {
private var items = listOf<HasStuff>()
fun add(a:HasStuff) { items += a }
}
答案 2 :(得分:0)
我们只是创建一个带变量的标准Kotlin类,扩展超类,并手工制作getter-setters?
差不多,是的,虽然没有使用变量但是使用属性。如果你的SuperClazz
没有任何字段,那么你可以将它转换为接口,数据类可以实现接口 - 你仍然必须实现这些方法,但是这样你就可以利用相同的架构(迭代超类型参数集合)。没有任何方法可以按照您描述的方式使用数据类自动属性。