1

假设我们有以下两个类:

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

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

将它们都设置为 case 类会导致两个param使用位置出现错误,这表示它需要override修饰符来覆盖父类的值。这对我来说看起来很奇怪..为什么我必须在这里发明其他参数名称..为什么要强制执行这种顺序?利润在哪里?

4

4 回答 4

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.
于 2012-01-12T15:25:54.430 回答
1

利润在哪里?

只是缺少一个不太有用的特殊情况。paramincase class MyChild(param: Int)是一个类成员以及一个构造函数参数,因此其中一个祖先已经有一个(非抽象)param成员,它必须被覆盖。Scalaoverride在覆盖其他任何地方时都需要关键字,因此这里也需要关键字。

于 2012-01-12T16:41:25.083 回答
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
于 2012-01-12T16:47:40.710 回答
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。这是一种告诉MyChildextends的方法MyParent,并首先调用后者的超级构造函数。

于 2012-01-12T14:21:59.653 回答