Как переопределить метод generi c в scala и вызвать его с отражением - PullRequest
0 голосов
/ 08 апреля 2020

Вот мой родительский класс


sealed trait Conf
sealed case class EmptyConf(value:String) extends Conf

abstract class EntryPoint() {
  def create[C <: Conf](conf: C): Definition
}

Вот ребенок

class TestEntryPoint extends EntryPoint {
  override def create(conf: EmptyConf): Definition = ???
}

Компилятор говорит:

class TestEntryPoint needs to be abstract, 
since method create in class EntryPoint of type [C <: Conf](conf: C)Definition 
is not defined

Что я делаю не так?

UPD: я пытался

abstract class EntryPoint[C <: Conf]() {
  def create(conf: C): Definition
}

class TestEntryPoint extends EntryPoint[EmptyConf] {
  override def create(conf: EmptyConf): Definition = ???
}

Тогда у меня возникают проблемы с его созданием с помощью отражения.

private def instantiate[P <: EntryPoint[_]](entryPointClass: Class[P],
                                                   conf: Conf): Definition = {
    entryPointClass.getConstructor()
      .newInstance()
      .create(conf)
  }

Он не скомпилируется, поскольку create ожидает подкласс Conf , Как я могу получить его во время выполнения?

UPD: Работает, спасибо. Просто добавьте немного грубой силы

entryPointClass.getDeclaredMethods
      .find(_.getName == "create")
      .map(_.invoke(instance, conf))
      .map(_.asInstanceOf[Definition])
      .getOrElse(throw DefinitionInstantiationException(
        s"Can't instantiate ${entryPointClass.getName} " +
          s"using configuration ${conf.getClass.getName}",
        new RuntimeException))

Не сохраняйте тип, хотя ...

1 Ответ

1 голос
/ 08 апреля 2020

Кажется, это то, что вы хотите

abstract class EntryPoint[C <: Conf]() {
  def create(conf: C): Definition
}

class TestEntryPoint extends EntryPoint[EmptyConf] {
  override def create(conf: EmptyConf): Definition = ???
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...