scala Scala继承参数化构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6497059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:08:39  来源:igfitidea点击:

Scala inherit parameterized constructor

scalainheritanceconstructor

提问by flying sheep

I have an abstract base class with several optional parameters:

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

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

Do i really need to explicitly repeat all parameters with the additional keywords override valon top?

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

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

Or is there a syntax like

或者是否有类似的语法

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

I don't even need anotherArg, just a way to pass all keyword args to the super constructor.

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



I really like Scala's idea about constructors, but if there isn't a syntax for that one, I'll be disappoint :(

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

采纳答案by axel22

You can just use a dummy name in the inherited class:

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

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

but you do have to repeat the default values. There is no need to override a val.

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

EDIT:

编辑:

Note that your abstract class should not be a case class. Extending case classes is now deprecated. You should use an extractorfor you abstract class instead:

请注意,您的抽象类不应是 case 类。现在不推荐扩展案例类。您应该为您的抽象类使用提取器

abstract class SomeHypothesis(val request: Boolean)

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

回答by Geoff Reedy

In my mind the policy of default values doesn't belong in the base class but should go on the concrete classes. I'd instead do the following:

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

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

The case class fields of SomeHypothesiswill fulfill the requirements of the Hypothesis trait.

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

As others have said, you can still use an extractor for pattern matching on the common parts:

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

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

回答by Techmag

I've spend DAYS bashing my head on the desk trying to understand why named params were not going into an extended class.

我已经花了几天的时间在桌子上猛击我的头,试图理解为什么命名参数没有进入扩展课程。

I tried traits, copy() you name it - me and the compiler were always at odds and when things did compile the values never got passed.

我尝试了traits,copy()你的名字——我和编译器总是不一致,当事情编译时,值永远不会被传递。

So to be clear if you have class

所以要清楚你是否有课

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

And you want to extend it:

你想扩展它:

class B extends A // does NOT compile 

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

You would think that a call to B like so:

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

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

Would in fact either NOT compile (sadly it does) or actually work (it does NOT)

事实上要么不编译(可悲的是它)或实际工作(它不)

Instead you need to create B as follows (yes this is a repeat of an above answer but it wasn't obvious at first when google led me here...)

相反,您需要按如下方式创建 B(是的,这是对上述答案的重复,但是当 google 将我带到这里时,起初并不明显......)

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

and now

现在

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

Both COMPILES and WORKS

编译和工作

I have not yet worked out all the combinations and permutations of what/when and where you can put default values in the class B constructor but I'm pretty sure that defaults can be specified in the definition of class B with "expected" results.

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

回答by rafalotufo

If Hypothesis is an abstract class, then I'd not have a constructor for it. I'd set those parameters as abstract attributes of the abstract class.

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

But then, in this case you do need the overridemodifier.

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