Scala继承参数化构造函数

时间:2011-06-27 18:09:58

标签: scala inheritance constructor

我有一个带有几个可选参数的抽象基类:

abstract case class Hypothesis(
    requirement: Boolean = false,
    onlyDays:   Seq[Int] = Nil,
    …
) extends Something {…}

我是否真的需要在顶部附加关键字override val明确重复所有参数

case class SomeHypothesis(
    anotherArg: SomeType,
    override val requirement: Boolean = false,
    override val onlyDays:   Seq[Int] = Nil,
    …
) extends Hypothesis(
    requirement,
    onlyDays,
    …
) {…}

或者是否有类似

的语法
case class SomeHypothesis(anotherArg: SomeType, **) extends Hypothesis(**) {…}

我甚至不需要anotherArg,只是将所有关键字args传递给超级构造函数的方法。


我真的很喜欢Scala关于构造函数的想法,但是如果没有这个构造函数的语法,我会很失望:(

4 个答案:

答案 0 :(得分:12)

您可以在继承的类中使用虚拟名称:

case class SomeHypothesis(anotherArg: SomeType, rq: Boolean = false, odays: Seq[Int] = Nil)
extends Hypothesis(rq, odays)

但您必须重复默认值。无需覆盖val

编辑:

请注意,您的抽象类不应该是案例类。现在扩展案例类deprecated。您应该使用extractor代替抽象类:

abstract class SomeHypothesis(val request: Boolean)

object SomeHypothesis {
  def unapply(o: Any): Option[Boolean] = o match {
    case sh: SomeHypothesis => Some(sh.request)
    case _ => None
  }
}

答案 1 :(得分:5)

在我看来,默认值的策略不属于基类,而应该属于具体的类。我会做以下事情:

trait Hypothesis {
  def requirement: Boolean
  def onlyDays: Seq[Int]
  /* other common attributes as necessary */
}

case class SomeHypothesis(anotherArg: SomeType,
                          requirement: Boolean = false,
                          onlyDays: Seq[Int] = Nil)
  extends Hypothesis

SomeHypothesis的案例类字段将满足假设特征的要求。

正如其他人所说,你仍然可以在公共部分使用提取器进行模式匹配:

object Hypothesis {
  def unapply(h: Hypothesis): (Boolean, Seq[Int]) = (h.requirement, h.onlyDays)
}

答案 2 :(得分:2)

我花了几天时间把头砸在桌子上试图理解为什么命名的参数不会进入扩展课程。

我尝试了traits,copy()你给它命名 - 我和编译器总是存在争议,当事情确实编译时,值永远不会通过。

所以要明确你是否有课

class A(someInt:Int = 0, someString: String ="xyz", someOtherString: String = "zyx")  

你想扩展它:

class B extends A // does NOT compile 

class B(someInt: Int, someString: String, someOtherString: String) extends A // compiles but does not work as expected 

你会认为对B的调用是这样的:

case object X = B(someInt=4, someString="Boo", someOtherString="Who") 

实际上要么不编译(遗憾的是它)或实际工作(它没有)

相反,你需要按如下方式创建B(是的,这是上述答案的重复,但是当谷歌带领我来到这里时,它并不是很明显......)

class B(someInt: Int, someString: String, someOtherString: String) extends A(someInt, someString, someOtherString) 

现在

case object X = B(someInt=4, someString="Boo", someOtherString="Who") 

汇编和工作

我还没有弄清楚你可以在B类构造函数中放置默认值的时间和地点的所有组合和排列,但我非常确定可以在B类的定义中指定默认值"预期"结果。

答案 3 :(得分:0)

如果假设是一个抽象类,那么我就没有它的构造函数。 ID 将这些参数设置为抽象类的抽象属性。

但是,在这种情况下,您需要override修饰符。