Kotlin没有静态的概念,但它有伴随对象。由于伴随对象是对象,所以可以使它们实现接口。
您可以通过以下方法(诚然是过度设计)来利用这一点:
-
使用不同的类型表示的族
Animal
(或者任何更适合你的术语,但犬科和猫科动物
家庭
根据我30秒的谷歌搜索:D)。
-
制作
动物
子类将其族宣传为属性,因此您可以访问的族
this
在您的功能中。
-
使每个动物类的伴侣对象实现
Family
接口,因此您可以在代码中使用类名来引用任何给定的族
动物
子类(您可以创建正则
object
s表示每个家庭,但使用同伴可以指代使用类名的家庭)
这给出了以下内容:
sealed interface Animal {
val family: Family<*>
}
interface Family<T : Animal> {
val nickname: String
}
class Canidae: Animal {
override val family = Canidae
companion object : Family<Canidae> {
override val nickname = "dog"
}
}
class Felidae: Animal {
override val family = Felidae
companion object : Family<Felidae> {
override val nickname = "cat"
}
}
inline fun <reified T : Animal, R> Animal.doSomething(family: Family<T>, f: (T) -> R): R =
if (this is T) {
f(this)
} else {
error("it's not a ${family.nickname}, it's a ${this.family.nickname}!")
}
你可以这样使用它:
animal.doSomething(Felidae) { println(it) }
不过,这种实现有一个缺点。你可能会犯错误
Canidae
类公开
Felidae
家族没有编译错误。
我们可以通过制作
动物
类递归泛型:
sealed interface Animal<T : Animal<T>> {
val family: Family<T>
}
interface Family<T : Animal<T>> {
val nickname: String
}
class Canidae: Animal<Canidae> {
override val family = Canidae
companion object : Family<Canidae> {
override val nickname = "dog"
}
}
class Felidae: Animal<Felidae> {
override val family = Felidae
companion object : Family<Felidae> {
override val nickname = "cat"
}
}
inline fun <reified T : Animal<T>, R> Animal<*>.doSomething(family: Family<T>, f: (T) -> R): R =
if (this is T) {
f(this)
} else {
error("it's not a ${family.nickname}, it's a ${this.family.nickname}!")
}