Метод абстрактного класса Scala, который возвращает новый соответствующий дочерний объект класса - PullRequest
5 голосов
/ 12 января 2012

Я имею в виду следующий класс:

abstract class MyClass (data: MyData) {

  def update(): MyClass = {
    new MyClass(process())
  }

  def process(): MyData = {
    ...
  }

}

Однако создание абстрактных классов невозможно, поэтому строка new MyClass(process()) является ошибкой.Мой вопрос - есть ли способ сообщить компилятору, что в случае каждого из дочерних классов MyClass я хочу создать объект именно этого дочернего класса?Кажется излишним писать этот метод во всех дочерних классах.Играя с параметрами типа класса или метода, я не мог достичь этого сам.

Ответы [ 2 ]

6 голосов
/ 12 января 2012

Как насчет этого? MyClass параметризован с конкретным типом. Конечно, все конкретные классы должны реализовывать метод, который фактически возвращает новый экземпляр Self.

trait MyClass[+Self <: MyClass[Self]] {
  def update(): Self = {
    makeNew(process())
  }

  def process(): MyData = {
    // ...
  }

  protected def makeNew(data: MyData): Self
}

class Concrete0 extends MyClass[Concrete0] {
  protected def makeNew(data: MyData) = new Concrete0
}

class RefinedConcrete0 extends Concrete0 with MyClass[RefinedConcrete0] {
  override protected def makeNew(data: MyData) = new RefinedConcrete0
}

Кредит: Второе обновление IttayD для своего ответа до на этот вопрос .

3 голосов
/ 13 января 2012

Чтобы полностью избежать реализации практически идентичного метода во всех подклассах, вам необходимо использовать рефлексию.Я думаю, это будет вашим последним средством, если вы выбрали Scala.Вот как минимизировать повторяющийся код:

// additional parameter: a factory function
abstract class MyClass(data: MyData, makeNew: MyData => MyClass) {

  def update(): MyClass = {
    makeNew(process())
  }
  def process(): MyData = {
    ...
  }
}

class Concrete(data: MyData) extends MyClass(data, new Concrete(_))

Таким образом, вы повторяете только самый короткий фрагмент, необходимый для создания экземпляра подкласса.

...