[РЕДАКТИРОВАНИЕ НИЖЕ]Производные классы как конструктор класса параметров
У меня есть иерархия классов, то есть, прямо сейчас, примерно следующим образом:
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
быть типа, соответствующего конкретный подкласс (Bar
или Baz
) из Foo
, но я получаю ошибку компиляции, как
... type mismatch;
[error] found : Any
[error] required: Array[String]
Поэтому у меня есть несколько вопросов:
- Я достаточно с Scala знаком поверить, что это правильный путь, чтобы представить свою конкретную проблему, но не достаточно с ним знаком, чтобы знать, как идти об этом. Каков правильный способ делать то, что я пытаюсь сделать?
- Кроме того, есть ли способ сказать класс
Qux
чтоm
следует рассматривать в качестве значения, возвращаемого определеннойmethod
изBar
илиBaz
, а не абстрактный метод изFoo
?
Edit: Принимая подход, предложенный @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
«s method
делать такие вещи. Тем не менее, сейчас я получаю сообщение об ошибке, как
[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] ^
Подобные ошибки появляются, когда я пытаюсь вызвать Map
Определённые методы на m
когда foo
является Baz
(вдоль линий value keys is not a member of Qux.this.foo.A
и т.д.). Я понимаю, что m
не действительно a Array[String]
- это тип A
. Но есть ли способ сказать Скале «перевести» это в свой желаемый тип?
«параметр типа», который может быть сдерживаются «граница». –