Scala子类型不被接受

时间:2012-09-02 10:08:22

标签: scala

我在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时,我使用该页面在地图中查找页面组件。必须有一个更好的方法,但如果没有,我很高兴。

2 个答案:

答案 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 {})

}

如果您想进行一些重构以获得更好的可组合性,请发布更多代码。

- 编辑 -

https://gist.github.com/3608684

答案 1 :(得分:0)

嗯,问题在于这个假设:

  

我认为因为P“是一个”页面

您没有声明PPage。这就是你声明的内容:

type P <: Page

这意味着PPage子类型。目前还不知道子类型是什么,事实上,除非您将initialise声明为相等,否则您永远无法将任何内容传递给P在某些时候。

问题是,你真的需要P <: Page吗?您是否只能说initialise需要Page,其中包含Page的所有子类型?