generics类的types约束?

假设我有以下代码:

sealed class Animal(val type: String) { data class Cat(val color: String) : Animal("cat") data class Dog(val mood: String , val ownersName : String) : Animal("dog") } abstract class AnimalDescriptor(val a: T) { abstract fun getSummary(): String } class CatDescriptor(a: Animal.Cat) : AnimalDescriptor(a) { override fun getSummary(): String { return "The color of this ${a.type} is ${a.color}" } } class DogDescriptor(a : Animal.Dog) : AnimalDescriptor(a) { override fun getSummary(): String { return "${a.ownersName}'s ${a.type} is ${a.mood}" } } fun main(args: Array) { fun summary(a : Animal) : String { return when(a) { is Animal.Cat -> CatDescriptor(a) is Animal.Dog -> DogDescriptor(a) }.getSummary() } val kitten = Animal.Cat("yellow") val doggy = Animal.Dog("happy" , "John") println(summary(kitten)) println(summary(doggy)) } 

输出是:

 The color of this cat is yellow John's dog is happy 

这确实是我想要的。

但是我觉得有点“腥”,因为AnimalDescriptor初始化中的重复types声明:

 class CatDescriptor(a: Animal.Cat) : AnimalDescriptor(a) 

而且,它不能禁止我们写这个class级:

 class ADescriptor(a : Animal) : AnimalDescriptor(a) { override fun getSummary(): String { return "type = ${a.type} " } } 

在这种情况下,这是没有意义的。

有更好的设计吗?

function风格,甚至Kategory合并是受欢迎的。

但至少保留sealed class设计。

KotlinConf 2017这张幻灯片引起了我的注意:

在这里输入图像说明 它打动了我的脑海

我不知道如果纯Kotlin(意味着没有其他第三库)能达到我的要求,但似乎与Kategory它可以做到这一点,是否有可能在Kategory? 怎么样 ?

—–更新回复@PaulHicks —–

AnimalDescriptor是不可避免的,如果我想在里面做一些template ,比如:

 abstract class AnimalDescriptor(val a: T) { fun sayHello() : String { return "Hello : " + getSummary() } abstract fun getSummary(): String } fun hello(a: Animal): String { return when (a) { is Animal.Cat -> CatDescriptor(a) is Animal.Dog -> DogDescriptor(a) }.sayHello() } val kitten = Animal.Cat("yellow") val doggy = Animal.Dog("happy", "John") println(hello(kitten)) println(hello(doggy)) 

并且,它输出:

 Hello : The color of this cat is yellow Hello : John's dog is happy