在Kotlin中实例化类型T.

时间:2018-04-01 10:04:24

标签: kotlin

简而言之,我想省略下面示例中重复的getT()。我看过Instantiating a generic type in Kotlin,但将() -> T作为参数'是什么意思?我怎样才能将它应用到下面?

interface Food
{
    var isHeated:Boolean;
    var name:String;
}

abstract class Cooker<T:Food>
{
    abstract fun getT():T;
    abstract fun enhance(t:T);
    fun cook(): T
    {
        var food = getT();
        food.isHeated = true;
        food.name = "heated " + food.name;
        enhance(food);
        return food;
    }
}

class PotatoChip:Food
{
    override var isHeated = false;
    override var name = "potato chip";
}

class PotatoChipCooker:Cooker<PotatoChip>()
{
    override fun getT(): PotatoChip {
        return PotatoChip();
    }
    override fun enhance(t:PotatoChip)
    {
        t.name = "salted " + t.name;
    }
}

class Pancake:Food
{
    override var isHeated = false;
    override var name = "pancake";
}

class PancakeCooker:Cooker<Pancake>()
{
    override fun getT(): Pancake {
        return Pancake();
    }
    override fun enhance(t:Pancake)
    {
        t.name = t.name + " coated with maple syrup";
    }
}

fun main(args: Array<String>)
{
    val result = PotatoChipCooker().cook();
    println(result.name);
    val result2 = PancakeCooker().cook();
    println(result2.name);
}

1 个答案:

答案 0 :(得分:5)

您可以将初始化函数作为主构造函数的一部分。因此,实现类必须传递一个函数,该函数指定如何创建相应的类型:

abstract class Cooker<T : Food>(private val initT: () -> T) {
    abstract fun enhance(t: T)
    fun cook(): T {
        val food = initT()
        food.isHeated = true
        food.name = "heated $name"
        enhance(food)
        return food
    }
}


class PotatoChipCooker : Cooker<PotatoChip>({ PotatoChip() }) {
    override fun enhance(t: PotatoChip) {
        t.name = "salted ${t.name}"
    }
}


class PancakeCooker : Cooker<Pancake>({ Pancake() }) {
    override fun enhance(t: Pancake) {
        t.name = "${t.name} coated with maple syrup"
    }
}

请注意,我删除了可选的分号并使用了字符串模板而不是连接。此外,cook方法可以简化为:

fun cook() = initT().apply {
    isHeated = true
    name = "heated $name"
    enhance(this)
}