2012-01-12 8 views
1

は、私たちが2つの以下のクラスがあるとしましょう:それらを両方のケースクラスを作るScalaの子ケースクラスのparam名前の競合

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

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

氏は述べている、両方のparamの利用場所でエラーが発生しました親クラスの値をオーバーライドする修飾子overrideが必要であることを示します。これは私にとって奇妙に見えます..なぜ私はここに他の名前をつけなければならないのですか。利益はどこですか?

答えて

7

あなたは他のケースクラスからケースクラスを派生させるべきではありません!

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

そのための迅速な修正プログラムは、これは実際にextends MyParent()は、Javaのようではありません。この

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

になります。この

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); 

を行うことです。これは、MyChildMyParentになるように指示し、最初に後者のスーパーコンストラクタを呼び出します。

1

利益は次のとおりです。

はREPLでこれを試してみてくださいはScalaの-deprecationで開始しましたか?

あまりにも便利すぎる特別なケースがないだけです。 case class MyChild(param: Int)paramはクラスメンバーでもコンストラクタパラメータでもあるため、祖先の1つが既に(抽象度の低い)paramメンバを持っているため、オーバーライドする必要があります。 Scalaでは他のすべてを上書きするときにはoverrideというキーワードが必要なので、ここでもそれが必要です。

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 
関連する問題