1

次の2つのクラスがあると仮定します。

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

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

それらを両方のケースクラスにすると、両方の使用場所でエラーが発生しました。これは、親クラスの値をオーバーライドする修飾子が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

私の限られた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 に答える
1

利益はどこにありますか?

あまり役に立たない特別なケースがないだけです。paramincase class MyChild(param: Int)はクラスメンバーであり、コンストラクターパラメーターでもあるため、祖先の1つには既に(非抽象)paramメンバーがあり、オーバーライドする必要があります。そして、Scalaはoverride他の場所をオーバーライドするときにキーワードを必要とするので、ここでもそれを必要とします。

于 2012-01-12T16:41:25.083 に答える