【问题标题】:Scala's case class and its constructor parameter passing to super classesScala 的案例类及其构造函数参数传递给超类
【发布时间】:2015-09-11 01:04:41
【问题描述】:

在 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
        ^

我看到这是由于案例类使构造函数参数不可变引起的,但是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

如何解决这个问题?

【问题讨论】:

    标签: scala class constructor


    【解决方案1】:

    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 类的参数(valvar)。考虑到上面的两个语句,您唯一的选择是在 case 类中引入另一个字段,然后将其传递给父构造函数。它会造成冗余并且不是好方法:

    abstract class A(var a: Int)
    class B(a: Int) extends A(a)
    case class C(param: Int) extends B(param)
    

    作为结论,我建议您避免将 case 类与 var 混用。案例类被设计成小的不可变 DTO。您可以使用案例类的copy 方法方便地更改一个或多个字段,同时保持不可变:

    case class C(a: Int)
    
    val b = C(10)
    println(b.a)
    val b1 = b.copy(a = 100)
    println(b1.a)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-26
      • 2010-12-12
      • 1970-01-01
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      相关资源
      最近更新 更多