我有一个实现接口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中实现呢?
答案 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
只是为了让你知道你应该放在哪个类型