web-dev-qa-db-ja.com

Scalaパラメーター化されたコンストラクターを継承する

いくつかのオプションのパラメーターを持つ抽象基本クラスがあります。

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も必要ありません。これは、すべてのキーワード引数をスーパーコンストラクターに渡す方法です。


コンストラクターに関するScalaのアイデアは本当に気に入っていますが、その構文がない場合はがっかりします:(

24
flying sheep

継承されたクラスでダミー名を使用できます。

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

ただし、デフォルト値を繰り返す必要があります。 valをオーバーライドする必要はありません。

編集:

抽象クラスはケースクラスであってはならないことに注意してください。ケースクラスの拡張は 非推奨 になりました。代わりに、抽象クラスに 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
  }
}
12
axel22

私の考えでは、デフォルト値のポリシーは基本クラスに属していませんが、具体的なクラスに適用する必要があります。代わりに、次のことを行います。

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)
}
5
Geoff Reedy

名前付きパラメータが拡張クラスに入れられなかった理由を理解するために、私は何日も机の上で頭を殴りました。

私は特性を試しました、あなたがそれを名付けた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") 

COMPILESとWORKSの両方

クラスBコンストラクターにデフォルト値を入れることができるもの/時期と場所のすべての組み合わせと順列をまだ解明していませんが、「期待される」結果でクラスBの定義にデフォルトを指定できると確信しています。

2
Techmag

Hypothesisが抽象クラスの場合、そのコンストラクターはありません。これらのパラメーターを抽象クラスの抽象属性として設定します。

ただし、この場合、override修飾子が必要です。

0
rafalotufo