是否有可能限制一个列表的类型为Kotlin接口的实现?
我有一个类Stealth
实现界面Skill
和一个类SoundlessMovement
实现界面Mastery
。 现在我想把Skill
Stealth
Skill
加入到SoundlessMovement
Skill
,同时确保Skill
支持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如何实施呢?
我不知道我是否真的了解你,但我认为这段代码解决了你的问题:
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的密封类
请注意, Self
不是一个保留字,也不是类似的东西。 代码也可以工作,如果你只是改变它只是T
我选择使用Self
只是为了让你知道你应该放在那里的类型