2017-08-09 117 views
7

我正在努力处理数据类和多态。我想从不变性中受益,但仍然能够更新我的状态。为此,我希望能够使用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 

现在我希望能够做这样的事(但不工作):

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

我怎样才能创造更新的副本多态的方式?

我试着给接口一个copy函数,但是如果子类型有其他属性,它们不会覆盖复制函数。
这是令人沮丧的,因为我知道亚型具有该属性,但我不能在界面中利用这些知识。

回答

4

[OP:]我想出的最好的是确实申报复制功能的界面:

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

这工作了数据类亚型,无需额外的属性框(即奶酪从问题)。对于具有附加属性的数据类子类型,您需要明确声明它,因为生成的copy函数不覆盖接口中的函数。

与它的年龄拷贝实现的亚型的样子:

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) 
} 

希望能更好的解决方案(或科特林改善;))。

编辑:更新后按照Ghedeons的建议。

+1

诱骗它选择正确的方法的另一种方法是复制参数具有不同的名称。例如:'重写有趣的副本(_age:Int)=副本(年龄= _age)'。 – Ghedeon