[英]Scala's case class and its constructor parameter passing to super classes
在 Scala 中,我可以將子類中的參數用於超類,如下所示:
abstract class A(var a:Int)
class B(a:Int) extends A(a)
class C(a:Int) extends B(a)
object Main extends App {
val b = new C(10)
println(b.a)
b.a = 100
println(b.a)
}
但是,對於案例類,我有錯誤:
abstract class A(var a:Int)
class B(a:Int) extends A(a)
case class C(a:Int) extends B(a) // case generates a as val
object Main extends App {
val b = C(10)
println(b.a) // without val, a is not accessible
b.a = 100
println(b.a)
}
這是消息:
case_simple.scala:8: error: reassignment to val
b.a = 100
^
我看到它是由 case 類引起的,使構造函數參數不可變,但我有C(var a:Int)
case_simple.scala:3: error: overriding variable a in class A of type Int;
variable a needs `override' modifier
case class C(var a:Int) extends B(a) // case generates a as val
^
one error found
並使用C(override var a:Int)
case_simple.scala:3: error: overriding variable a in class A of type Int;
variable a cannot override a mutable variable
case class C(override var a:Int) extends B(a) // case generates a as val
如何解決這個問題?
1.
當你有這樣的建築時:
abstract class A(var a: Int)
class B(a: Int) extends A(a)
類B
中的a
是傳遞給A
的父構造函數的構造函數參數。 為清楚起見,它可以改寫為:
abstract class A(var a: Int)
class B(param: Int) extends A(param)
param
不是類B
的成員, B
仍然只有一個從類A
派生的變量a
。
2. 在 scala 中不可能覆蓋var
。 似乎沒有意義,但我找不到明確的解釋。
現在進入正題。
案例類對參數有特殊處理。 語法是有限的,你不能定義不會是類成員的 case 類的參數( val
或var
)。 考慮到上面的兩個語句,您唯一的選擇是在 case 類中引入另一個字段,然后將其傳遞給父構造函數。 它會產生冗余並且不是好方法:
abstract class A(var a: Int)
class B(a: Int) extends A(a)
case class C(param: Int) extends B(param)
作為結論,我建議您避免將 case 類與 vars 混合。 Case 類被設計為小型的不可變 DTO。 您可以使用 case 類的copy
方法方便地更改一個或多個字段,同時保持不可變:
case class C(a: Int)
val b = C(10)
println(b.a)
val b1 = b.copy(a = 100)
println(b1.a)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.