Наследовать общие атрибуты c в Scala - PullRequest
0 голосов
/ 14 января 2020

Учитывая следующие значения class и trait, я пытаюсь создать подкласс с определенным типом c, т. Е. Engage и Event. Это то, что у меня есть на данный момент:

trait ATrait extends scala.AnyRef {
   val test: Option[String]
}

Я могу добиться следующего, но не очень много пользуюсь (так как класс abstract все еще)

// this is made 'abstract' by me (can be edited)
abstract class BaseSchema[T, P] extends ATrait {
  val test: Option[String]
  val data: T
  val parent: P
}

abstract class SubClass(override val data: Engage,
                        override val parent: Event
                       ) extends BaseSchema [Engage, Event]

Если Я преобразую Подкласс в class или case class. Мне нужно будет реализовать все абстрактные члены.

Как правильно справиться с этим в scala? В Java можно было бы сделать

abstract class BaseSchema<T,P> {
    T data;
    P parent;
}

class SubClass extends BaseSchema<Engage, Event> {
}

class Engage{} class Event{}

SubClass subClass = new SubClass();
Engage eng = subClass.data;

1 Ответ

5 голосов
/ 14 января 2020

Я думаю, что проблема в том, что вы не определяете реализацию ATrait.test. Поскольку это val, оно должно быть реализовано, чтобы иметь значение; поэтому любой подтип, который его не реализует, должен быть abstract (либо trait, либо abstract class). Этот элемент отсутствует в Java версии вашего примера.

В этом решении я присвоил ему значение None в BaseSchema, так как нет никаких указаний как это должно быть определено. Если вы можете привести пример того, как это должно выглядеть, это поможет.

Кстати, в Scala, если у вас есть abstract class без аргументов, тогда вместо этого он может быть определен как trait, что делает вещи немного более гибкими, так как его можно затем смешивать с базовым классом. Вот пример с этим (и обратите внимание, что SubClass больше не abstract), в пределах Scala REPL :

C:\SomeDir>scala
Welcome to Scala 2.13.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions for evaluation. Or try :help.

scala> class Engage
defined class Engage

scala> class Event
defined class Event

scala> trait ATrait {
     |   val test: Option[String]
     | }
defined trait ATrait

scala> trait BaseSchema[T, P] extends ATrait {
     |   override val test: Option[String] = None
     |   val data: T
     |   val parent: P
     | }
defined trait BaseSchema

scala> class SubClass(override val data: Engage, override val parent: Event) extends BaseSchema[Engage, Event]
defined class SubClass

Если вы хотите сделать SubClass a case class, тогда это путь; просто добавьте final case перед определением SubClass ( все классы должны быть объявлены final):

scala> final case class SubClass(override val data: Engage, override val parent: Event) extends BaseScheme[Engage, Event]
defined class SubClass

В качестве альтернативы вы можете сделать data и parent параметры BaseSchema, и в этом случае он должен быть определен как abstract class (если вы не хотите, чтобы он создавался как ) или class; в обоих случаях ни data, ни parent не являются абстрактными. Действительны оба следующих определения:

scala> abstract class BaseSchema[T, P](val data: T, val parent: P) extends ATrait {
     |   override val test: Option[String] = None
     | }
defined class BaseSchema

или

scala> class BaseSchema[T, P](val data: T, val parent: P) extends ATrait {
     |   override val test: Option[String] = None
     | }
defined class BaseSchema

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

scala> class SubClass(d: Engage, p: Event) extends BaseSchema[Engage, Event](d, p)
defined class SubClass

Действительно, так как Типы generi c могут быть выведены из параметров, это также может быть упрощено до:

scala> class SubClass(d: Engage, p: Event) extends BaseSchema(d, p)
defined class SubClass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...