如何在Kotlin中创建包含嵌入类的类对象?

时间:2018-07-12 06:03:02

标签: android kotlin

MySettings类在代码A中包含两个嵌入类,如何创建MySettings对象? 看来fun initA()不能是两个嵌入类的实例。

我意识到代码A的构造是错误的,所以我写代码B,不知道有没有好的方法!

代码A

class MySettings(val _id: Long) {

    data class MyBluetooth(
            val status: Boolean = false
    )

    data class WiFiDef(
            val name: String,
            val status: Boolean = false
    )
}


fun initA(){
  var myObject =MySettings(10L)
}

代码B

class MySettings(val _id: Long) {
   var aMyBluetooth: MyBluetooth? =null
   var aWiFiDef: WiFiDef?=null
}


data class MyBluetooth(
            val status: Boolean = false
 )

data class WiFiDef(
            val name: String,
            val status: Boolean = false
)


fun initB(){
   var myObject =MySettings(10L)
   myObject.aMyBluetooth=MyBluetooth(false)
   myObject.aWiFiDef=WiFiDef("name",true)
}

3 个答案:

答案 0 :(得分:0)

就您的问题而言,代码A 是绝对正确的。

但是,如果我们在您的代码A 代码B 之间进行比较,则在最适合的情况下会有不同的情况。

方案1:良好的编程习惯

如果您想遵循Kotlin的良好编程习惯,请遵循代码B,因为编写可重用的代码是一种良好的做法。还有一件事,您可以像这样在代码B中实例化您的对象。

fun initB(){
    var myObject =MySettings(10L, aMyBluetooth=MyBluetooth(false), 
                             aWiFiDef=WiFiDef("name",true))
}

方案2:内部类

您的代码A在要在kotlin中实现内部类的情况下很有用。内部类可以访问外部类的成员。但是在这种情况下,数据类不能是内部的。

class MySettings(val _id: Long) {

    inner class MyBluetooth(
            val status: Boolean = false
    )

    inner class WiFiDef(
            val name: String,
            val status: Boolean = false
    )
}


fun initA(){
  var myObject =MySettings(10L)
}

我希望这可以清除您的查询。

答案 1 :(得分:0)

如果以某种方式组合代码A和代码B,则可以将数据类保留在MySettings中:

class MySettings(val _id: Long) {
    val blueTooth = MyBluetooth(true)
    val wiFiDef = WiFiDef("wifi", true)

    data class MyBluetooth(
            val status: Boolean = false
    )

    data class WiFiDef(
            val name: String,
            val status: Boolean = false
    )
}


fun initA(){
    val myObject = MySettings(10L)
    val myBlueTooth = myObject.blueTooth
    val myWiFiDef = myObject.wiFiDef
} 

此后,您可以决定如何将val中的所有var更改为MySetings来使用数据类的实例。但这是暴露它们的一种方式。

答案 2 :(得分:0)

我会采用这样的方法:

  1. 使用Kotlin构造函数,该构造函数可以使用类作用域变量。只需在构造函数中标记这些可为空(通过?),然后让用户决定是否要初始化这些变量
  2. 使所有设置(蓝牙和wifi)都从密封类扩展而来,尤其是因为它们之间有公共变量。

总而言之,我将这样编写这段代码:

class MySettings(val id: Long, val bluetooth: Setting.MyBluetooth? = null, val wifi: Setting.WifiDef? = null) {

    sealed class Setting(val status: Boolean = false) : Serializable {
        class WifiDef(
                status: Boolean,
                val name: String
        ): Setting(status)

        class MyBluetooth(
                status: Boolean
        ): Setting(status)
    }
}

fun init() {
    val mySettings = MySettings(10L, bluetooth = MySettings.Setting.MyBluetooth(true))
    val bluetooth = mySettings.bluetooth
    val wifi = mySettings.wifi
}

在谈论实现此目的的其他方法时,我强烈建议不要在类内部对任何值进行硬编码,尤其是当您内部具有某些类的实例时,尤其是这样。如果有什么变化,稍后将无法重构