我是Kotlin的初学者,我使用代码a定义一个复杂的类MDetail,并使用代码B创建一个对象aMDetail1,它可以工作。
但是数据结构太糟糕,无法扩展,如果像代码C一样在MDetail中包含一个新的数据类,如ScreenDef,那么所有旧代码都必须重写。
对于包含一些类的复杂类,有没有好的数据构造?我希望将来数据构造可以很容易地扩展!
代码A
data class BluetoothDef(val Status:Boolean=false)
data class WiFiDef(val Name:String, val Status:Boolean=false)
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi:WiFiDef
)
代码B
var mBluetoothDef1= BluetoothDef()
var mWiFiDef1= WiFiHelper(this).getWiFiDefFromSystem()
var aMDetail1= MDetail(7L,mBluetoothDef1,mWiFiDef1)
代码C
data class BluetoothDef(val Status:Boolean=false)
data class WiFiDef(val Name:String, val Status:Boolean=false)
data class ScreenDef(val Name:String, val size:Long)
...
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi:WiFiDef
val aScreenDef:ScreenDef
...
)
下面的代码是基于s1m0nw1所说的,我认为它很容易在将来扩展。谢谢
有没有其他更好的方法?
版本1代码
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
class MDetail(val _id: Long, val devices: MutableList<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
class UIMain : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
val btD = BluetoothDef(true)
val wfD = WiFiDef("MyWifi")
val xSc = ScreenDef("MyScreen", 1)
val m = MDetail(7L, mutableListOf(btD, wfD, xSc))
handleBluetoothDef(m.getDevice<BluetoothDef>())
handleWiFiDef(m.getDevice<WiFiDef>())
handleScreenDef(m.getDevice<ScreenDef>())
}
fun handleBluetoothDef(mBluetoothDef:BluetoothDef){ }
fun handleWiFiDef(mWiFiDef:WiFiDef){ }
fun handleScreenDef(mScreenDef:ScreenDef){ }
}
版本2代码(扩展)
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
data class TimeLine(val Name: String): DeviceDef //Extend
class MDetail(val _id: Long, val devices: MutableList<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
class UIMain : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
val btD = BluetoothDef(true)
val wfD = WiFiDef("MyWifi")
val xSc = ScreenDef("MyScreen", 1)
val aTe = TimeLine("MyTimeline") //Extend
val m = MDetail(7L, mutableListOf(btD, wfD, xSc,aTe)) //Modified
handleBluetoothDef(m.getDevice<BluetoothDef>())
handleWiFiDef(m.getDevice<WiFiDef>())
handleScreenDef(m.getDevice<ScreenDef>())
handleTimeLine(m.getDevice<TimeLine>()) //Extend
}
fun handleBluetoothDef(mBluetoothDef:BluetoothDef){}
fun handleWiFiDef(mWiFiDef:WiFiDef){ }
fun handleScreenDef(mScreenDef:ScreenDef){ }
fun handleTimeLine(mTimeLine:TimeLine){} //Extend
帮助
我必须用开放类替换接口,因为我无法从json字符串GSON中取消序列化MDetail对象。
但是有趣的是
open class DeviceDef
data class BluetoothDef(val status:Boolean=false): DeviceDef()
data class WiFiDef(val name:String, val status:Boolean=false) : DeviceDef()
data class MDetail(val _id: Long, val deviceList: MutableList<DeviceDef>)
{
inline fun <reified T> getDevice(): T {
return deviceList.filterIsInstance(T::class.java).first()
}
}
每次将新属性添加到MDetail中时,请将新属性标记为null,并将默认值设置为null。像这样
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi: WiFiDef,
val screen: ScreenDef? = null,
...
)
不要忘记在创建新实例时,提供特定的属性名称,如下所示
var aMDetail1= MDetail(7L, mBluetoothDef1, mWiFiDef1, screen = mScreenDef1)
我不是Kotlin专家,但我建议在MDetail的构造函数中添加默认值
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi:WiFiDef
val aScreenDef:ScreenDef? = null,
val aGpsDef: GpsDef = GpsDef()
...
)
或者,如果您不希望ascreenedef为空,请为其添加一个默认值,如示例。通过这种方式,您可以保持现有的构造函数调用不变,并在需要时向构造函数调用添加新值此外,您还可以使用命名参数功能,在该功能中,您可以在调用构造函数时指定参数的名称。因此,如果要在不添加屏幕定义的情况下将GpsDef添加到MDetail,可以执行以下操作
val detail = MDetail(id, bluetooth, wifi, aGpsDef = GpsDef())
请注意,如果您使用的是来自Java的构造函数,则可能需要对构造函数使用JVMLowloads注释,该注释告诉编译器根据具有默认值的可选参数生成多个构造函数。
我建议执行以下操作:您的单元(Wifi、蓝牙等)应该由一个接口抽象(至少作为一个标记),该接口可以命名为DeviceDef
。
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
可以使用这些设备的变量列表实例化MDetail
类,以便在添加新设备(例如ScreenDef
)时无需修改:
class MDetail(val _id: Long, val devices: List<DeviceDef>)
在MDetail
中,您可以提供过滤这些设备的方法:
class MDetail(val _id: Long, val devices: List<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
现在,使用WifiDef
非常简单,例如:
fun main(args: Array<String>) {
val btD = BluetoothDef()
val wfD = WiFiDef("")
val m = MDetail(7L, listOf(btD, wfD, ScreenDef("", 1)))
println(m.getDevice<WiFiDef>())
}
我希望这能有所帮助。如果没有,您可能需要提供有关MDetail
应该如何工作的更多详细信息。
我需要包括一些必须在许多tmpls中重复的php代码。我怎么能做到这一点,可能是因为类包括?我怎么能写PHP文件与我的类在一个正确的方式?换句话说,我需要像 视图/类别/胎压监测/默认值。php 视图/文章/TPM/默认值。php 我的班级。php ... 更新:@Guilherme谢谢你!所以现在看起来 文件/mytemplate/html/com\u content/article/defau
但任何时候我用这个: 我得到一个隐秘的错误: 我尝试使用自定义数据类型: 使用返回该类型的UDF: 但随后我得到另一个,它抱怨类型。 如何正确地编写可以返回复杂类型的UDF?
问题内容: 我正在尝试为我们试图解决的遗传问题建模,并逐步加以解决。我可以从Spark示例成功运行PiAverage示例。该示例将一个圆圈“掷飞镖”(在本例中为10 ^ 6),并计算“落在圆圈中”的数量以估算PI 假设我要重复该过程1000次(并行),并对所有这些估计求平均值。我正在尝试寻找最好的方法,似乎会有两个调用要并行化?嵌套通话?有没有办法将地图链接或减少通话数量?我看不到 我想知道以下想
生活中描述事物无非就是描述事物的 属性 和 行为。 如:人有身高,体重等属性,有说话,打架等行为。 事物名称(类名):人(Person) 属性:身高(height)、年龄(age) 行为(功能):跑(run)、打架(fight) Go 语言中用类来描述事物也是如此 属性:对应类中的成员变量。 行为:对应类中的成员方法。 定义类其实在定义类中的成员(成员变量和成员方法) 拥有相同或者类似 属性(
问题内容: 如果我有几个具有所需功能的类,但想单独存储以进行组织,我可以扩展一个类以同时拥有这两个类吗? 即 编辑:我知道如何一次扩展一个类,但是我正在寻找一种使用多个基类立即扩展一个类的方法- AFAIK,您不能在PHP中做到这一点,但是应该有一些解决方法,而不必诉诸于, 问题答案: 回答您的编辑: 如果您确实想伪造多重继承,则可以使用魔术函数__call()。 尽管从A类用户的角度来看,这很丑
所以我有一个多项目设置,看起来像这样