我在scala中有这个类
trait PageComponent {
protected var page:Page = _
protected var pageData:PageData = _
def initialise(page0:Page, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
PageComponent 的每个子类都有自己的 Page 和 PageData 子类。当子类调用 page 或 pageData 时,我希望它为此返回它自己的类型。
我试过类似的东西
trait PageComponent {
type P <: Page
protected var page:P = _
protected var pageData:PageData = _
def initialise(page0:P, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
这样的工作使得子类可以调用页面并获取通过实现类型 P 定义的页面类型。
但是,我正在尝试调用初始化方法,我正在传递一个 Page 类型的对象,它显示了这个错误
error: type mismatch;
found : pageInfoToGoTo.page.type (with underlying type com.xxx.gui.Page)
required: pageComponentToGoTo.P
pageComponentToGoTo.initialise(pageInfoToGoTo.page, pageData)
我在这里显然是错误的,但我认为因为 P“是一个”页面,所以这应该对我有用。
有什么想法吗?
-----编辑更多信息------
我确实有类似的东西
class AhoyPage extends Page
object MyPageComponent extends PageComponent {
type P = AhoyPage
}
在阅读了 jwinandy 的回答后,我更改了代码,以便以这种方式调用初始化方法
pageComponentToGoTo.initialise(pageInfoToGoTo.page.asInstanceOf[pageComponentToGoTo.P], pageData)
现在可以了。所以我想我的问题得到了回答。谢谢。那个 Actor 不是很好。我有一个如下所示的 PageInfo 列表
PageInfo(page:Page, ...)
当一个 PageInfo 被选中时,我使用该页面在 map 中查找页面组件。一定有更好的方法,但如果没有,我对此很满意。
最佳答案
子类化时必须定义 P。
在你的情况下,你必须拥有:
type P = com.xxx.gui.Page
例如,这个有效:
trait Page
trait PageData
trait PageComponent {
type P <: Page
protected var page:P = _
protected var pageData:PageData = _
def initialise(page0:P, pageData0:PageData) {
page = page0
pageData = pageData0
}
}
class AhoyPage extends Page
object MyPageComponent extends PageComponent {
type P = AhoyPage
}
object MyApp extends App {
MyPageComponent.initialise(new AhoyPage, new PageData {})
// OR
MyPageComponent.initialise(new MyPageComponent.P, new PageData {})
}
如果您想稍微重构一下以实现更好的可组合性,请发布更多代码。
-- 编辑--
关于Scala 子类型不被接受,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12235062/