をパラメータとして[BELOW EDITED]派生クラスクラスのコンストラクタは
私は、おおまかに以下の、今、あるクラス階層を持っている:
sealed trait Foo {
def method: Any
}
case class Bar extends Foo {
def method: Array[String] = // implementation
}
case class Baz extends Foo {
def method: Map[String, Array[String]] = // implementation
}
私は抽象メソッドにAny
の戻り値の型を与えていますなぜなら、ケースクラスの戻り値の型は必然的に異なるからですが、それらは同じ目的を共有しているからです。このような理由から、私はその共通の振る舞いをモデル化するためにそれを特性に残しておきたいと思います。これがコンパイルされた唯一の方法です。これがScalaの型システムの精神に反していることを認識しているので、私は以下の最初の質問をします。
その後、別のクラスは、コンストラクタのパラメータとしてFoo
のサブクラスを期待して、私は次の以外、これを意味するのか分からない:
class Qux(foo: Foo) {
val m = foo.method
...
...
}
後半クラスQux
で期待する方法がありますヴァルm
はFoo
の特定のサブクラス(Bar
またはBaz
)に対応するタイプのものであると、私は
... type mismatch;
[error] found : Any
[error] required: Array[String]
のようなコンパイルエラーを取得しています
- 私はこれが私の特定の問題を表現するための正しい方法であると信じてするのに十分なスカラ座に精通していますが、それについて移動する方法を知っているのに十分それに慣れていない:
は、だから私は、カップルの質問があります。私がやろうとしていることをする正しい方法は何ですか?
- また、
m
がBar
またはBaz
から特定のmethod
によって返された値、およびないFoo
から抽象メソッドとして扱われるべきであるというクラスQux
を伝える方法はありますか?
編集:は(抽象型メンバーを使用して)@mariosによって提案されたアプローチを取るには、正しい方向への第一歩であると考えられるが、型の不一致は今ポップアップ表示されます。クラスQux
の中で、私は今
class Qux[X <: Foo](sc: SparkContext, val foo: X) {
val m: foo.A = foo.method
def process(rows: DataFrame) = foo match {
case Bar(sc, _) => BarProcessor(sc, m).doStuff(rows)
case Baz(sc, _) => BazProcessor(sc, m.keys).doStuff(rows, m.values)
}
}
を有する場合BarProcessor
は、例えば、でインスタンスArray[String]
、およびBazProcessor
は、ものを行うためにBaz
のmethod
によって返された値からキーと値のペアを必要としています。私はfoo
は(value keys is not a member of Qux.this.foo.A
の線に沿って、など)Baz
ときm
にMap
固有のメソッドを呼び出すしようとすると、しかし、私は今
[error] Qux.scala:4: type mismatch;
[error] found : Qux.this.foo.A
[error] required: Array[String]
[error] case Bar(sc, _) => BarProcessor(sc, m).doStuff(rows)
[error] ^
同様のエラーのようなエラーが発生しますが現れます。 m
はではありません。Array[String]
- A
です。しかし、Scalaにこれを望ましいタイプに「翻訳」するよう指示する方法はありますか?
"バウンド" によって制約することができ、 "typeパラメータを"(戻り値の型を見てください)。 –