[英]case class extending trait with abstract type
我有几个这样的案例类:
case class Size(id: Long, size: Int)
case class Title(id: Long, title: String)
.
.
.
我有10个具有几乎相同的功能。 我决定将它们组合在一个共同的特征之下,这导致了这样的事情:
trait Property[T]{
val value: T
}
trait PropertyPair[T]{
val id: Long
val prop: Property[T]
}
case class Size(id: Long, prop: Property[Int]) extends PropertyPair[Int] {
def size: Int = prop.value
}
case class Title(id: Long, prop: Property[String]) extends PropertyPair[String] {
def title: String = prop.value
}
虽然上面的代码块似乎是一个很好的解决方案,现在我可以在PropertyPair
特性下实际定义函数,但代码仍然有气味。
[T]
三次 现在初始化Title
我需要写
Title(101L, Property("Title"))
代替
Title(101L, "Title")
出于某种原因,我确信有一个更优雅,更不容易出错的解决方案,而不是我提供的解决方案。
你不需要2个级别,可以用abstract class
替换trait
来使用它的构造函数:
sealed abstract class Property[T](val prop: T) {
val id: Long
}
case class Size(id: Long, size: Int) extends Property[Int](size)
case class Title(id: Long, title: String) extends Property[String](title)
这些情况中的每一个都具有Property
类所需的id
值,但是如果您希望它们具有prop
不同名称,您可以将它们作为prop
值传递给Property
构造函数。
然后它可以用作
val size = Size(101L, 42)
val title = Title(202L, "Foo")
这是一个简单的解决方案。 对于更一般的情况,我建议你这样做:
sealed trait AnyProperty {
val id: Long
type Prop
val prop: Prop
}
sealed abstract class Property[T](
val prop: T
) extends AnyProperty {
type Prop = T
}
(其余的都一样)
这种方法的优点是,您可以使用顶级特征来引用任何属性,例如
def foo[P <: AnyProperty](p: P): Long = p.id
foo(size) // 101L
例如,您可以参考Prop
类型成员
def buh[P <: AnyProperty](p: P): P#Prop = p.prop
buh(title) // "Foo"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.