我在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)
它现在有效。所以我想我的问题得到了回答。谢谢。那个演员虽然不是很好。我有一个如下所示的PageInfo列表
PageInfo(page:Page, ...)
当选择PageInfo时,我使用该页面在地图中查找页面组件。必须有一个更好的方法,但如果没有,我很高兴。
答案 0 :(得分:2)
您必须在子类时定义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 {})
}
如果您想进行一些重构以获得更好的可组合性,请发布更多代码。
- 编辑 -
答案 1 :(得分:0)
嗯,问题在于这个假设:
我认为因为P“是一个”页面
您没有声明P
是Page
。这就是你声明的内容:
type P <: Page
这意味着P
是Page
的子类型。目前还不知道子类型是什么,事实上,除非您将initialise
声明为相等,否则您永远无法将任何内容传递给P
在某些时候。
问题是,你真的需要P <: Page
吗?您是否只能说initialise
需要Page
,其中包含Page
的所有子类型?