扩展scala案例类而不经常复制构造函数的vals?

Lal*_*lin 58 inheritance scala

有没有办法扩展一个案例类,而不是不断地沿途获取新的val?例如,这不起作用

case class Edge(a: Strl, b: Strl)
case class EdgeQA(a: Strl, b: Strl, right: Int, asked: Int) extends Edge(a, b)
Run Code Online (Sandbox Code Playgroud)

"a"与"a"冲突,所以我被迫重命名为a1.但我不想要各种额外的"a"公开副本,所以我把它变成了私人的.

case class Edge(a: Strl, b: Strl)
case class EdgeQA(private val a1: Strl, private val b1: Strl, right: Int, asked: Int) extends Edge(a, b)
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎并不干净..我错过了什么吗?

小智 64

正如之前的评论者所提到的:应该避免使用案例类扩展,但是您可以将Edge类转换为特征.

如果要避免使用私有语句,还可以将变量标记为覆盖

trait Edge{
  def a:Strl
  def b:Strl
}

case class EdgeQA(override val a:Strl, override val b:Strl, right:Int, asked:Int ) extends Edge
Run Code Online (Sandbox Code Playgroud)

不要忘了喜欢defval的特质

  • 我们失去了Edge作为独立类的优势:在它可以被实例化之前它具有对象Factory方法 (12认同)
  • 你能解释为什么def在性状上是首选吗? (7认同)
  • 但是我仍然需要重新声明a和b.如果特征具有某个默认值并且是,并且我希望自己使用这些值,该怎么办? (6认同)
  • `"应该避免案例类扩展".你能解释一下为什么,@ bajohns? (5认同)

dav*_*rez 41

该解决方案比以前的解决方案具有一些优势:

trait BaseEdge {
  def a: Strl
  def b: Strl
}
case class Edge(a:Strl, b:Strl) extends BaseEdge
case class EdgeQA(a:Strl, b:Strl, right:Int, asked:Int ) extends BaseEdge
Run Code Online (Sandbox Code Playgroud)

通过这种方式:

  • 你没有多余val的,和
  • 你有2个案例类.

  • 这绝对是更好的 (2认同)

小智 12

案例类不能通过子类扩展.或者更确切地说,案例类的子类本身不能是案例类.

  • 敢解释为什么? (11认同)
  • 除了使用case类扩展case类的内置限制之外,Final还是防止用任何东西扩展case类(例如case和not case类). (7认同)
  • 那么为什么还有"最终案例类"?`final` _LocalModifier_是阻止`case class`扩展的原因,而不是其他语言禁止.参见[Scala参考]的第5.2节,第63页(http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference.pdf) (4认同)

Xav*_*hot 5

从 开始Scala 3特征可以有参数

trait Edge(a: Strl, b: Strl)
case class EdgeQA(a: Strl, b: Strl, c: Int, d: Int) extends Edge(a, b)
Run Code Online (Sandbox Code Playgroud)