是否可以将List的类型限制为Kotlin中接口的实现?

时间:2017-09-18 08:49:22

标签: kotlin

我有一个实现接口Stealth的类Skill和一个实现接口SoundlessMovement的类Mastery。现在,我想将精通SoundlessMovement添加到Skill Stealth,同时确保Mastery支持Skill

我想做这样的事情(Pseudo-Kotlin):

interface Skill {
    val masteries: List<Mastery<Skill>> // Mastery linked to type Skill
}

interface Mastery<Skill> { // Every Mastery must be compatible with only one Skill
    val masteryName: String
}

实施:

class Stealth : Skill {
    override val masteries: ArrayList<Mastery<Stealth>() // Any Mastery bound to Stealth
}

class SoundlessMovement : Mastery<Stealth> { // Is a Mastery compatible with Stealth
    override val masteryName = "Soundless Movement"
}

目标是确保只能将兼容的制作者添加到技能中。 这样的事情甚至可能吗?如果是的话,怎么能在Kotlin中实现呢?

1 个答案:

答案 0 :(得分:3)

我不知道我是否真的了解你,但我认为这段代码可以解决你的问题:

interface Mastery<Skill> {
    val masteryName: String
}

interface Skill<Self : Skill<Self>> {                              // forces every Skill to bound to itself
    val masteries: List<Mastery<Self>>
}

abstract class Stealth : Skill<Stealth> {
    override val masteries = ArrayList<Mastery<Stealth>>()
}

class SoundlessMovement : Mastery<Stealth> {         // a Stealth mastery
    override val masteryName = "Soundless Movement"
}

class SoundlessMovement2 : Mastery<Stealth> {        // another Stealth mastery
    override val masteryName = "Soundless Movement 2"
}

abstract class Archery : Skill<Archery> {         
    override val masteries = ArrayList<Mastery<Archery>>()
}

class SureShot : Mastery<Archery> {                  // some other mastery
    override val masteryName = "Sure shot 2"
}

fun main(args: Array<String>) {

    var list = ArrayList<Mastery<Stealth>>()

    list.add(SoundlessMovement())            // compiles
    list.add(SoundlessMovement2())           // compiles
    list.add(SureShot())                     // Doesn't compile
}

这里的关键是使用Skill<Self>来绑定当前的实现。另请注意,我已将class Stealth ...更改为abstract class Stealth ...,因为您定义掌握类型。另一种选择可能是使用Kotlin's sealed class

请注意Self 不是保留字,也不是类似的。如果您只是将其更改为T,代码也会起作用。我选择使用Self只是为了让你知道你应该放在哪个类型