Scala继承参数化构造函数

Scala继承参数化构造函数,scala,inheritance,constructor,Scala,Inheritance,Constructor,我有一个抽象基类,有几个可选参数: abstract case class Hypothesis( requirement: Boolean = false, onlyDays: Seq[Int] = Nil, … ) extends Something {…} 我真的需要用附加关键字override val在顶部显式重复所有参数吗 或者有类似的语法吗 case class SomeHypothesis(anotherArg: SomeType, **) exten

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

abstract case class Hypothesis(
    requirement: Boolean = false,
    onlyDays:   Seq[Int] = Nil,
    …
) extends Something {…}
我真的需要用附加关键字
override val
在顶部显式重复所有参数吗

或者有类似的语法吗

case class SomeHypothesis(anotherArg: SomeType, **) extends Hypothesis(**) {…}
我甚至不需要
另一个arg
,只需要一种将所有关键字arg传递给超级构造函数的方法



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

您可以在继承的类中使用一个伪名称:

case class SomeHypothesis(anotherArg: SomeType, rq: Boolean = false, odays: Seq[Int] = Nil)
extends Hypothesis(rq, odays)
但您必须重复默认值。无需覆盖
val

编辑:

请注意,您的抽象类不应是case类。扩展case类现在是。您应该改用for-your抽象类:

abstract class SomeHypothesis(val request: Boolean)

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

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


但是,在这种情况下,您确实需要
覆盖
修饰符。

在我看来,默认值的策略不属于基类,而应该属于具体类。我将改为执行以下操作:

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
some假说
的案例类字段将满足假说特征的要求

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

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

我花了好几天的时间在桌子上捶着头,试图理解为什么命名参数没有进入扩展类

我试过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(是的,这是对上述答案的重复,但最初google引导我到这里时并不明显…)

现在呢

case object X = B(someInt=4, someString="Boo", someOtherString="Who") 
既编译又工作


我还没有计算出可以在B类构造函数中放置默认值的内容/时间和位置的所有组合和排列,但我非常确定可以在B类的定义中使用“预期”指定默认值结果。

但Mr编译器不同意:
重写布尔类型的类假设中的值要求;值要求需要“override”修饰符
(当我添加它时,Mr编译器告诉我,
“val”是预期的,但找到了标识符。
)啊,现在我明白你的意思了:使用其他名称可以避免重写内容。但这只是一个小麻烦,因为我仍然需要为所有子类重新编写所有内容。一点也不枯燥>:(很抱歉,我忽略了您使用案例类的要点。但是-无论如何,您不应该有一个抽象案例类-扩展案例类是一个不推荐使用的功能。什么?为什么?我应该做什么?关于案例类继承不推荐使用的讨论:。您应该使用提取器:无论如何,我需要它,请参阅我对其他答案的评论。)。此外,它们总是相同的,并且总是具有相同的默认值,因此我不会从抽象类的构造函数中保存超过两个括号。我想保存所有重复。如果可以,我会否决此注释,因为它是错误的。至少对我来说,情况并非如此。请参阅第一条注释。我想你应该这样做用默认参数试试。(或者我的编译器做的事情与你的不同,但我对此表示怀疑。)它与默认参数无关,但您是对的:在这种情况下确实需要
override
。由于您使用的是case类,所有构造函数参数都隐式具有
val
修饰符。由于名称冲突,您必须添加显式
override
修饰符(还有一个显式的
val
修饰符,让解析器高兴)。很抱歉我的评论太仓促。我的问题仍然是我不应该重复我自己。我真的希望有一个在所有子类中行为相同的共享构造函数接口。所以每次我写
name:Type=default
,我都会重复我自己三次。(应该是0)那么也许它们不应该是不同的子类。相反,有一个由额外数据参数化的假设类。可能类似于
案例类假设[t](信息:t,要求:Boolean=false,onlyDays:Seq[Int]=Nil)
但可能需要在T上绑定一个类型以确保某些通用接口。听起来不错。事实上,我需要一个需求、一个期望和一些过滤器(仅限日期等)。然后我需要对过滤后的数据应用一个函数,必须对其中一些函数进行分组(可以提供分组标准)。然后,我需要通过期望(“在0到0.05的范围内”、“真”、“低”)来评估功能结果。此评估的结果可用于需求中。(强调所有参数)
class B(someInt: Int, someString: String, someOtherString: String) extends A(someInt, someString, someOtherString) 
case object X = B(someInt=4, someString="Boo", someOtherString="Who")