scala - 如何为 val 分配一个 trait 的实现?
问题描述
我有以下特征和类:
trait A{
def func1: String
def func2: Int
}
class F extends A{
def func1: String = ???
def func2: Int = ???
}
class G extends A{
def func1: String = ???
def func2: Int = ???
}
我想创建以下特征和类:
trait X{
val a: ***
}
class Z extends X{
override val a = new G
}
我需要在 trait X 中的 '***' 上写什么,以便我可以将 val a 分配给 F 或 G 类?谢谢你。
编辑
抱歉,我忘了说特征 A 是 A[Any],特征 F 和 G 可以是 'F extends A[String]' 和 'G extends A[Int]'。换句话说,类可以使用不同类型的参数扩展特征 A。
解决方案
关于。您的编辑,您的代码失败,因为特征 A 仅采用固定类型的类型参数。如果您声明基类具有A[Any]
,则不能用A[Int]
或覆盖它A[String]
。有两种方法可以使您的代码正常工作。
一种是制作 trait A 类型参数covariant
,以便您可以使用您在基类中声明的类型参数的子类覆盖(注意+
in trait A 定义):
trait A[+T]
class F extends A[String]
class G extends A[Int]
trait X {
val a: A[Any]
}
class Z extends X {
val a = new G
}
见这里:样品
另一种工作方式是将 a 声明为A[_]
(_
意味着它将任何类型作为参数,这与Any
) 不同:
trait A[T]
class F extends A[String]
class G extends A[Int]
trait X {
val a: A[_]
}
class Z extends X {
val a = new G
}
见这里:样品
推荐阅读
- c# - 如何处理类库中调用应用程序的退出?
- hl7 - 无法从 HL7 REF^I12 消息中获取 OBR 段
- android - Android,FileNotFound 异常,但被 Glide 发现没有问题。问题是什么?
- vue.js - Vuex 结合命名空间模块和常量类型
- firebase - Firebase Auth 导致 Gradle 失败
- react-native - React Native iOS 上的默认标题垂直高度太高,我该如何更改?
- android - Laravel API Rest 在设备 Android 中不起作用
- android - Chrome 的自动隐藏 URL 栏弄乱了我的背景渐变
- r - 识别同一行中的相似名称,然后选择模式
- arabic - Mathjax 阿拉伯语