kotlin - 如何更新实现通用接口(interface)的数据类

标签 kotlin data-class

我正在为数据类和多态性而苦苦挣扎。我想从不变性中受益,但仍然能够更新我的状态。为此,我希望能够使用 copy 功能。

让我们举个例子。我有这个类层次结构:

interface Aging {
  val age : Int
}

data class Cheese (
  override val age : Int
  // more Cheese specific properties
) : Aging

data class Wine (
  override val age : Int,
  val grape : String
  // more Wine specific properties
) : Aging   

现在我希望能够做这样的事情(但 this 不起作用):

class RipeningProcess(){
  fun ripen(products : List<Aging>) =
    // Not possibe, no copy function on Aging
    products.map { it.copy(age = it.age + 1) } 
}

如何以多态方式创建更新的副本?

我尝试为接口(interface)提供 copy 函数,但如果子类型具有其他属性,它们不会覆盖复制函数。
这很令人沮丧,因为我知道子类型具有该属性,但我无法在界面中利用该知识。

最佳答案

[OP:] 我想出的最好的方法确实是在界面中声明复制功能:

interface Aging {
  val age : Int
  fun copy(age : Int) : Aging
}

这适用于没有附加属性的数据类子类型(即问题中的奶酪)。对于具有附加属性的数据类子类型,您需要显式声明它,因为生成的 copy 函数不会覆盖接口(interface)中的那个。

具有年龄复制实现的子类型如下所示:

data class Wine(
  override val age : Int,
  val grape : String
) : Aging {

  // Different parameter name, to avoid conflict with generated copy method
  override fun copy(_age: Int) = copy(age = _age)
}

希望有更好的解决方案(或 Kotlin 改进;))。

编辑:已更新以遵循 Ghedeons 的建议。

关于kotlin - 如何更新实现通用接口(interface)的数据类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45584242/

相关文章:

java-8 - Kotlin 中的 javax.time

ubuntu - 如何使用 Kotlin 的反射?

lambda - 不使用对象的 Kotlin lambda

Json 到 Kotlin 数据类

使用多重继承构建Python对象

google-app-engine - 如何使用 Kotlin DSL 配置 AppEngine Gradle 插件

Kotlin 数据类 : how to set a property if I don't know its name at compile time?

android - 在 kotlin 中将数据类(JSON 对象)转换为列表

lambda - lambda 表达式的函数

javascript - 如何使用 Highcharts 指向数据中第二个索引的范围(dataClasses)?