泛型类类型约束?

时间:2017-12-19 00:54:59

标签: generics kotlin

假设我有以下代码:

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<out T : Animal>(val a: T) {
  abstract fun getSummary(): String
}

class CatDescriptor(a: Animal.Cat) : AnimalDescriptor<Animal.Cat>(a) {
  override fun getSummary(): String {
     return "The color of this ${a.type} is ${a.color}"
  }
}

class DogDescriptor(a : Animal.Dog) : AnimalDescriptor<Animal.Dog>(a) {
  override fun getSummary(): String {
    return "${a.ownersName}'s ${a.type} is ${a.mood}"
  }
}

fun main(args: Array<String>) {

  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初始化中的重复类型声明:

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

此外,它不能禁止我们写这个课:

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

在这种情况下,这是毫无意义的。

有更好的设计吗?

欢迎功能风格甚至Kategory合并。

但至少要保留sealed class设计。

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

enter image description here It blows my mind

我不确定纯Kotlin(没有其他第3个库的方式)是否可以达到我的要求,但似乎Kategory它可以做到这一点,它是否可能在Kategory?怎么样?

-----更新回复@PaulHicks -----

如果我想在里面做一些AnimalDescriptor

template是不可避免的,例如:

abstract class AnimalDescriptor<out T : Animal>(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

0 个答案:

没有答案