java - 在 Scala 中继承通用属性
问题描述
鉴于以下class
and trait
,我想要实现的是创建一个具有自己特定类型的子类,即Engage
and 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]
如果我将 SubClass 转换为 aclass
或 acase 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;
解决方案
我认为这里的问题是您没有定义ATrait.test
. 由于这是一个val
必须实现的值;因此,任何未实现它的子类型都必须是抽象的( atrait
或 an abstract class
)。您的示例的Java版本中缺少此成员。
在这个解决方案中,我给了它一个None
in的值BaseSchema
,因为没有说明它应该如何定义。如果你能提供一个应该是什么样子的例子,那会有所帮助。
顺便说一句,在Scala中,如果你有一个abstract class
不带参数的 a,那么它可以被定义为 a trait
,这使得事情更加灵活,因为它可以混合在一起,也可以作为一个基类。这是一个在Scala REPL中完成的示例(注意SubClass
不再是abstract
):
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
一个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
或者,您可以 makedata
和parent
参数BaseSchema
,在这种情况下,它必须定义为abstract class
(如果您不希望它按原样实例化)或 a 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
实际上,由于可以从参数中推断出泛型类型,因此也可以将其简化为:
scala> class SubClass(d: Engage, p: Event) extends BaseSchema(d, p)
defined class SubClass
推荐阅读
- django - Django:模型字段中的用户列表
- r - 更精确地在 r 中导入数据
- r - 从嵌套列表中进行有效抽样
- android - React Native 如何手动将 API 级别更改为 26
- python - 机器人唤醒时向所有用户发送消息
- mysql - 从表中选择一个有限的数字,但全部从连接的表中连接
- java - android旋转屏幕导致文本颜色更改为默认值
- amazon-web-services - 将主机 IP 地址分配给 Docker 容器
- python - 数据抓取 Python - 在 href 中获取标签
- python - 构造 ClassDict 的预期参数为零(对于 pyspark.ml.linalg.SparseVector)