2017-03-04 53 views
0

我有一個類是2個類的摘要。我做了這個類數據類,如下具有派生屬性的Kotlin數據類

data class Device(private val deviceModel: DeviceModel, private val deviceStatus: DeviceStatusModel) { 
    val name = deviceModel.name ?: "Unknown" 
    val id = deviceModel.id ?: -1 
    val mode = when(deviceStatus.mode) { 
     1 -> DEVICE_MODE_MANUAL 
     2 -> DEVICE_MODE_AUTO 
     3 -> DEVICE_MODE_OVERRIDE 
     else -> DEVICE_MODE_MANUAL 
    } 
    val strength = deviceStatus.strength ?: 0 
} 

但是當我打印這個類未打印的姓名,身份證,模式和強度性能,它打印設備型號和設備狀態。有沒有辦法讓這個類根據派生屬性生成toString而不是構造函數?

回答

2

DeviceModel和DeviceStatusModel用於toString(),因爲您通過主構造函數將它們聲明爲屬性以執行所需操作,您必須使用輔助構造函數從中調用主構造函數,並在其中聲明屬性你想在的toString(看到)這樣的:

import kotlin.properties.Delegates 
import kotlin.collections.MutableList 

const val DEVICE_MODE_MANUAL = 10 
const val DEVICE_MODE_AUTO = 20 
const val DEVICE_MODE_OVERRIDE = 30 

data class Device private constructor (val name: String, val id: Int, val mode: Int, val strength: Int) { 

    constructor(deviceModel: DeviceModel, deviceStatus: DeviceStatusModel ) : 
    this(
     name = deviceModel.name ?: "Unknown", 
     id = deviceModel.id ?: -1, 
     mode = when(deviceStatus.mode) { 
      1 -> DEVICE_MODE_MANUAL 
      2 -> DEVICE_MODE_AUTO 
      3 -> DEVICE_MODE_OVERRIDE 
      else -> DEVICE_MODE_MANUAL 
     }, 
     strength = deviceStatus.strength ?: 0 
    ) 
} 

data class DeviceModel(val name: String, val id: Int) 

data class DeviceStatusModel(val mode: Int, val strength: Int) 

fun main(args: Array<String>) { 
    val deviceModel = DeviceModel("Test ", 35) 
    val deviceStatusModel = DeviceStatusModel(1, 42) 
    val device = Device(deviceModel, deviceStatusModel) 
    println(device) 
} 

NB:我認爲你不希望人們實例化對象的其他方式比通過DeviceModel和DeviceStatusModel所以我做了主構造私人

+0

謝謝,這是一個聰明的解決方案,它允許在調用默認的toString的同時爲調用者​​保留一個簡單的構造函數。 – Francesc

6

您可以覆蓋toString()方法並提供您需要的任何實現,而不是默認的編譯器生成的實現。

+0

是的,這是顯然是一個選項,但我想知道是否有辦法告訴編譯器自動生成的方法需要考慮哪些屬性,必須覆蓋它們,這樣做會破壞數據類的目的。我想我將不得不改變構造函數,並且如果沒有其他方式,在調用方執行邏輯。 – Francesc

+1

有一種方法可以告訴編譯器:通過在toString()方法中編寫代碼。當我們已經有了一個完美的通用語言來完成這個任務時,我們不想提出一種用於描述toString()和equals()應該如何工作的替代迷你語言。 – yole

+0

@Francesc https://kotlinlang.org/docs/reference/data-classes.html中的第一句話是*我們經常創建一個類,除了保存數據*外什麼也不做。數據類有一個唯一的目的來存儲數據,所以只考慮構造函數屬性並不能真正地達到目的。如果你在構建一個實例時需要一些邏輯,而是使用一個更靈活的工廠或者構建器 – D3xter