Scala子案例类param名称与父案例类param名称冲突

时间:2012-01-12 14:12:40

标签: scala parameters case-class

让我们假设我们有以下两个类:

abstract case class MyParent(param: Int) {
   // ...
}

case class MyChild(param: Int) extends MyParent(param: Int) {
   // ...          ^^^^^                        ^^^^^
}

将它们作为案例类导致两个param使用位置都出错,这表示它需要覆盖父类值的override修饰符。这对我来说很奇怪..为什么我必须在这里发明其他的param名称..为什么这个事情的顺序是强制执行的?利润在哪里?

4 个答案:

答案 0 :(得分:7)

你永远不应该从另一个案例类派生一个案例类!

在以 scala -deprecation 开头的REPL中尝试此操作:

scala> case class Foo(foo: String)
defined class Foo

scala> case class Bar(override val foo: String) extends Foo(foo)
<console>:9: warning: case class `class Bar' has case ancestor `class Foo'.  Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed.  You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes.

答案 1 :(得分:1)

快速修复此问题

abstract case class MyParent(param: Int) {
   println("Form parent : " + param)
}

case class MyChild(override val param: Int) extends MyParent(param) {
   println("Form child : " + param)
}

val c = MyChild(10);

这将导致此

>> From parent : 10 
>> From child : 10 

实际上extends MyParent()与Java不同。这是一种告诉MyChild extends MyParent的方法,并且首先调用后者的超级构造函数。

答案 2 :(得分:1)

  

利润在哪里?

缺少一个不太有用的特殊情况。 param中的case class MyChild(param: Int)是一个类成员以及一个构造函数参数,因此其中一个祖先已经有一个(非抽象)param成员,必须重写它。 override关键字,所以它也需要它。

答案 3 :(得分:1)

就我有限的Scala知识而言,案例类通常用于不可变的代数数据类型和模式匹配。因此,您可能应该创建一个包含“父”类的类,而不是创建“子类”。

> case class MyParent(param: Int)
defined class MyParent

> case class MyChild(param: Int, parent: MyParent)
defined class MyChild

> def foo(c: MyChild) = c match {
    case MyChild(p, MyParent(p2)) => println("p: " + p + ", p2 " + p2)
  }
foo: (c: MyChild)Unit

> foo(MyChild(3, MyParent(4)))
p: 3, p2 4