将继承的Java bean转换为Kotlin
在当前的Java类中,我们有两个Java bean Clazz1和Clazz2,它们都扩展了超类SuperClazz。 我们也有一个列表,我们迭代超级类的条目,可以是Clazz1或Clazz2:
List<SuperClazz> entries;
我们现在需要将代码转换为Kotlin,但由于数据类不支持继承,所以我们不能确定解决这个问题的最佳方式,我们只需创建一个带变量的标准Kotlin类,扩展超类,手工制作getter -setters? 或者,有没有更好的方法来做到这一点?
通常有2种(不是相互的)方式可以消除对类继承的需求:
1.使用组合
将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 } } }
2.使用接口
从上面的例子可以很容易的看出,你可以提取一个接口来表示Class1
和Class2
的公共Class1
,如下所示:
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
作为类。 您也可以在共享界面上拥有更多的成员,并且通过Kotlin的授权仍然可以实现简洁。 (但是通常有更好的“小”接口 )
我们决定这样做:
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 } }
我们只是创建一个带有变量的标准Kotlin类,扩展超类,并手动制作吸气器?
很多,是的,虽然不是与变量,但具有属性 。 如果您的SuperClazz
没有任何字段,那么您可能可以将其转换为接口,而数据类可以实现接口 – 但您仍然必须实现这些方法,但这样可以使您使用相同的体系结构(迭代超级类型的参数集合)。 在描述的方式中没有任何方法使用数据类自动属性。
- 如何为Kotlin和Gradle设置“sourceCompatibility”?
- 运行Kotlin代码时,Android Studio会抛出java.lang.ClassNotFoundExceptionexception
- 如何在IntelliJ插件中执行Kotlin代码?
- 为什么kotlin lambda反编译为java代码是(Function0)null.INSTANCE
- Java 8中的map和flatMap方法有什么区别?
- 是否有可能用Kotlin val(property)重写Java getter(method)?
- 如何返回像javawith Kotlin接口
- Gradle和Realm库的编译问题
- 除非明确引用,否则Kotlin无法识别参数